zoukankan      html  css  js  c++  java
  • oc之mac中自定义NSSlider

    Mac开发之重写NSSlider(比酷狗的播放进度条好看)

    2018年03月15日

    Mac开发如果觉得系统自带Slider不好看,可以通过重绘让自己软件的Slider变得好看一点。与iOS开发不同的是,Mac开发控件重绘没有那么直接,但也不算复杂。下面说一下怎么通过继承NSSlider和NSSliderCell重绘NSSlider。

    新建一个Project,名字为:CustomSlider。打开Main.storyboard,从IB中拉几个slider,如图一所示:

     

    图一

    新建几个类,分别是CustomSlider、CustomSliderCell和NSColor+Hexa,下面是这几个类的详细内容:

    CustomSlider.h

    //  CustomSlider.h

    //  Created by Chen Ling on 15/3/2018.

    //  Copyright © 2018 Chen Ling. All rights reserved.

    #import <Cocoa/Cocoa.h>

    @interface CustomSlider : NSSlider

    @end

    CustomSlider.m

    #import "CustomSlider.h"

    @interface CustomSlider()

    @property (nonatomic, strong) NSTrackingArea *trackingArea;

    @end

    @implementation CustomSlider

    - (instancetype)initWithCoder:(NSCoder *)coder {

        if (self = [super initWithCoder:coder]) {

        }

        return self;

    }

    #pragma mark - 设置mouse追踪区域

    -(void)updateTrackingAreas

    {

        [super updateTrackingAreas];

        if(_trackingArea != nil) {

            [self removeTrackingArea:_trackingArea];

        }

        int opts = (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways)

        // 将设置追踪区域为控件大小

        // 设置鼠标追踪区域,如果不设置追踪区域,mouseEnteredmouseExited会无效

        _trackingArea = [ [NSTrackingArea alloc] initWithRect:[self bounds]

                                                      options:opts

                                            owner:self

                                                     userInfo:nil];

          [self addTrackingArea:_trackingArea];

    }

    - (void)drawRect:(NSRect)dirtyRect {

        [super drawRect:dirtyRect];

        // Drawing code here.

    }

    #pragma mark - 点击knob效果, 屏蔽就没有点下去的效果

    - (BOOL)needsPanelToBecomeKey{

        [super needsPanelToBecomeKey];

        return YES;

    }

    //- (BOOL)becomeFirstResponder{

    //    [super becomeFirstResponder];

    //    return YES;

    //}

    #pragma mark - mouse action

    - (void)mouseEntered:(NSEvent *)theEvent

    {

        [super mouseEntered:theEvent];

        NSLog(@"mouseEntered");

        self.highlighted = YES;

    }

    - (void)mouseExited:(NSEvent *)theEvent

    {

        [super mouseExited:theEvent];

        NSLog(@"mouseExited");

        self.highlighted = NO;

    }

    @end

    CustomSliderCell.h

    #import <Cocoa/Cocoa.h>

    #define ColorWithRGB(colorCode)     [NSColor colorWithDeviceRed:((colorCode>>16)&0xFF)/255.0 green:((colorCode>>8)&0xFF)/255.0 blue:((colorCode)&0xFF)/255.0 alpha:1.0];

    #define SLIDER_PROGRESS_DEFAUT_COLOR       ColorWithRGB(0x3399FF)

    #define SLIDER_BACKGROUND_DEFAUT_COLOR     ColorWithRGB(0x969696)

    #define SLIDER_KNOB_DEFAUT_COLOR           ColorWithRGB(0x3399FF)

    #define SLIDER_DEFAUT_HEIGHT               3.0

    #define SLIDER_DEFAUT_BAR_RADIUS           5.0

    #define SLIDER_DEFAUT_KNOB_WIDTH           8.0

    #define SLIDER_DEFAUT_KNOB_HEIGHT          8.0

    IB_DESIGNABLE

    @interface CustomSliderCell : NSSliderCell

    @property (nonatomic, strong) IBInspectable NSColor *sliderProgressColor;

    @property (nonatomic, strong) IBInspectable NSColor *sliderBackgroundColor;

    @property (nonatomic, strong) IBInspectable NSColor *sliderKnobColor;

    @property (nonatomic, assign) IBInspectable CGFloat sliderHeight;

    @property (nonatomic, assign) IBInspectable CGFloat sliderBarRadius;

    @property (nonatomic, assign) IBInspectable CGFloat sliderKnobWidth;

    @property (nonatomic, assign) IBInspectable CGFloat sliderKnobHeight;

    @end

    CustomSliderCell.m

    #import "CustomSliderCell.h"

    #import "NSColor+Hexa.h"

    #import "CustomSlider.h"

    @interface CustomSliderCell()

    @property (assign) NSRect leftBarRect;

    @end

    @implementation CustomSliderCell

    -(instancetype)initWithCoder:(NSCoder *)coder {

        if (self = [super initWithCoder:coder]) {

            self.sliderProgressColor = SLIDER_PROGRESS_DEFAUT_COLOR;

            self.sliderBackgroundColor = SLIDER_BACKGROUND_DEFAUT_COLOR;

            self.sliderKnobColor = SLIDER_KNOB_DEFAUT_COLOR;

            self.sliderHeight = SLIDER_DEFAUT_HEIGHT;

            self.sliderBarRadius = SLIDER_DEFAUT_BAR_RADIUS;

            self.sliderKnobWidth = SLIDER_DEFAUT_KNOB_WIDTH;

            self.sliderKnobHeight = SLIDER_DEFAUT_KNOB_HEIGHT;

        }

        return self;

    }

    - (void)drawBarInside:(NSRect)rect flipped:(BOOL)flipped {

        rect.size.height = self.sliderHeight;

        CGFloat barRadius = self.sliderBarRadius;

        CGFloat value = ([self doubleValue]  - [self minValue]) / ([self maxValue] - [self minValue]);

        CGFloat finalWidth = value * ([[self controlView] frame].size.width - self.sliderKnobWidth);

        NSRect leftRect = rect;

        leftRect.size.width = finalWidth;

        self.leftBarRect = leftRect;

        NSBezierPath* bg = [NSBezierPath bezierPathWithRoundedRect: rect xRadius: barRadius yRadius: barRadius];

        [self.sliderBackgroundColor setFill];

        [bg fill];

        NSBezierPath* active = [NSBezierPath bezierPathWithRoundedRect: leftRect xRadius: barRadius yRadius: barRadius];

        [self.sliderProgressColor setFill];

        [active fill];

    }

    - (void)drawKnob:(NSRect)knobRect {

        if (((CustomSlider *)self.controlView).highlighted) {

            NSRect customKnobRect = NSMakeRect(_leftBarRect.size.width, _leftBarRect.origin.y + _leftBarRect.size.height / 2 - self.sliderKnobHeight / 2, self.sliderKnobWidth, self.sliderKnobHeight);

            NSBezierPath* bg = [NSBezierPath bezierPathWithRoundedRect: customKnobRect xRadius: self.sliderKnobWidth / 2 yRadius: self.sliderKnobHeight / 2];

            [self.sliderKnobColor  setFill];

            [bg fill];

        }

    }

    @end

    NSColor+Hexa.h

    #import <Cocoa/Cocoa.h>

    @interface NSColor (Hexa)

    + (NSColor *)colorFromHexadecimalValue:(NSString *)hexaString;

    @end

    NSColor+Hexa.m

    #import "NSColor+Hexa.h"

    @implementation NSColor (Hexa)

    + (NSColor *)colorFromHexadecimalValue:(NSString *)hexaString {

        if ([hexaString hasPrefix:@"#"]) {

            hexaString = [hexaString substringWithRange:NSMakeRange(1, [hexaString length] - 1)];

        }

        unsigned int colorCode = 0;

        if (hexaString) {

            NSScanner *scanner = [NSScanner scannerWithString:hexaString];

            (void)[scanner scanHexInt:&colorCode];

        }

        return [NSColor colorWithDeviceRed:((colorCode>>16)&0xFF)/255.0 green:((colorCode>>8)&0xFF)/255.0 blue:((colorCode)&0xFF)/255.0 alpha:1.0];


    }

    @end

    将前面那三个NSSlider的类分别设置为CustomSlider,将它们的NSSliderCell的类设置为CustomSliderCell,在NSSliderCell的Attributes Inspector中分别设置为如图二图三图四所示:

    pastedGraphic_1.png        

    图二

    pastedGraphic_2.png

    图三

    pastedGraphic_3.png

    图四

    运行效果:

    pastedGraphic_4.png

    github地址:https://github.com/Mozartisnotmyname/CustomSlider

  • 相关阅读:
    第6章 静态路由和动态路由(2)_路由汇总和默认路由
    第6章 静态路由和动态路由(1)_静态路由
    第5章 IP地址和子网划分(4)_超网合并网段
    第5章 IP地址和子网划分(3)_子网划分
    第5章 IP地址和子网划分(2)_IP地址分类和NAT技术
    第5章 IP地址和子网划分(1)_IP格式和子网掩码
    第4章 数据链路层(5)_高速以太网
    第4章 数据链路层(4)_扩展以太网
    第4章 数据链路层(3)_广播信道的数据链路
    第4章 数据链路层(2)_点到点信道的数据链路
  • 原文地址:https://www.cnblogs.com/sundaymac/p/10337573.html
Copyright © 2011-2022 走看看