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

猜你喜欢

转载自www.cnblogs.com/sundaymac/p/10337573.html