美文网首页
macOS开发之自定义Slider

macOS开发之自定义Slider

作者: chasitu | 来源:发表于2021-07-05 11:21 被阅读0次

今天分享一个自定义的silider,因为系统自带的使用起来有诸多不便,主要的一个原因就是系统自带的未选中区域是透明的,也许小伙伴们有别的思路或者别的解决方案,我这里直接就基于NSView自定义了一个,代码也比较简单,也有注释,我就不多讲解了,直接上代码

效果图

SHSlider.h

#import <Cocoa/Cocoa.h>
typedef void(^ChangeValueBlock)(float value);
NS_ASSUME_NONNULL_BEGIN

@interface SHSlider : NSView
@property (nonatomic , strong , nonnull) NSColor *selectColor;//选中区域颜色
@property (nonatomic , strong , nonnull) NSColor *unSelectColor;//未选中区域颜色
@property (nonatomic , strong , nonnull) NSColor *cachColor;//缓冲区域颜色
@property (nonatomic , strong , nonnull) NSColor *valueColor;//圆圈颜色
@property (nonatomic , assign) float  value;//值,默认:0
@property (nonatomic , assign) float  cacheValue;//缓冲值
@property (nonatomic , assign) float  maxValue;//缓冲值,默认:100
@property (nonatomic , copy) ChangeValueBlock   changeValueBlock;
@end

NS_ASSUME_NONNULL_END

SHSlider.m

#import "SHSlider.h"

@interface SHSlider ()
@property (nonatomic , strong) NSView           *selectView;//选中视图
@property (nonatomic , strong) NSView           *unSelectView;//未选中视图
@property (nonatomic , strong) NSView           *cacheView;//缓冲
@property (nonatomic , strong) NSImageView      *valueView;//圆球
@property (nonatomic , strong) NSTrackingArea   *trackingArea;//监听鼠标
@property (nonatomic , assign) BOOL             isDragged;//正在拖动
@property (nonatomic , assign) float              minValue;//缓冲值,默认:0
@end

@implementation SHSlider
- (BOOL)isFlipped{return YES;}
- (BOOL)mouseDownCanMoveWindow{return NO;}
- (instancetype)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.wantsLayer = YES;
        self.layer.masksToBounds = NO;
        self.value = 0;
        self.cacheValue = 0;
        self.minValue = 0;
        self.maxValue = 100;
    }
    return self;
}
- (void)layout
{
    if (self.frame.size.width == 0) return;
    CGFloat padding = 2;
    if (self.isDragged == NO) {
        CGFloat location = self.value*(self.bounds.size.width-11)/self.maxValue;
        self.unSelectView.frame = NSMakeRect(0, padding, self.bounds.size.width, self.bounds.size.height-padding);
        self.selectView.frame = NSMakeRect(0, padding, location, self.bounds.size.height-padding);
        self.valueView.frame = NSMakeRect(location < 5 ? 0 : location - 5, self.bounds.size.height*0.5-5, 11, 11);
    }
    if (_cacheView && self.cacheValue <= self.maxValue) {
        CGFloat cache = self.cacheValue*self.bounds.size.width/self.maxValue;
        self.cacheView.frame = NSMakeRect(0, padding, cache, self.bounds.size.height - padding);
    }
}
#pragma mark - 监听鼠标
- (void)updateTrackingAreas
{
    if (self.trackingAreas.count > 0) {
        [self removeTrackingArea:_trackingArea];
    }
    _trackingArea = [[NSTrackingArea alloc] initWithRect:self.bounds options:(NSTrackingEnabledDuringMouseDrag|NSTrackingActiveInActiveApp|NSTrackingInVisibleRect|NSTrackingAssumeInside|NSTrackingCursorUpdate)owner:self userInfo:nil];
    [self addTrackingArea:_trackingArea];
}
- (void)mouseDown:(NSEvent *)event
{
    NSPoint point = NSMakePoint(event.locationInWindow.x-self.frame.origin.x, 0);
    if (NSPointInRect(point, self.valueView.frame)) {
        self.isDragged = YES;
    }
}
- (void)mouseUp:(NSEvent *)event
{
    self.isDragged = NO;
}
- (void)mouseDragged:(NSEvent *)event
{
    if (self.isDragged == YES) {
        self.value = (event.locationInWindow.x-self.frame.origin.x)/(self.bounds.size.width-6)*self.maxValue;
        CGFloat padding = 2;
        CGFloat location = self.value*(self.bounds.size.width-6)/self.maxValue;
        self.selectView.frame = NSMakeRect(0, padding, location, self.bounds.size.height-padding);
        self.valueView.frame = NSMakeRect(location < 5 ? 0 : location-5, self.bounds.size.height*0.5-5, 11, 11);
        !self.changeValueBlock ? : self.changeValueBlock(self.value);
    }
}
#pragma mark - 赋值
- (void)setValue:(float)value
{
    if (value <= self.maxValue && value >= self.minValue) {
        _value = value;
        if (self.maxValue - value <= 0.01) {
            _value = self.maxValue;
        }else if(value <= 0.01){
            _value = self.minValue;
        }
        [self layout];
    }
}
- (void)setCacheValue:(float)cacheValue
{
    if (cacheValue <= self.maxValue && self.bounds.size.height > 0 ) {
        _cacheValue = cacheValue;
        if (!_cacheView) {
            [self addSubview:self.cacheView positioned:NSWindowBelow relativeTo:self.selectView];
        }
        [self layout];
    }
}
- (void)setCachColor:(NSColor *)cachColor
{
    _cachColor = cachColor;
    self.cacheView.layer.backgroundColor = cachColor.CGColor;
}
- (void)setValueColor:(NSColor *)valueColor
{
    _valueColor = valueColor;
    self.valueView.layer.backgroundColor = valueColor.CGColor;
}
- (void)setSelectColor:(NSColor *)selectColor
{
    _selectColor = selectColor;
    _selectView.layer.backgroundColor = selectColor.CGColor;
}
- (void)setUnSelectColor:(NSColor *)unSelectColor
{
    _unSelectColor = unSelectColor;
    self.unSelectView.layer.backgroundColor = unSelectColor.CGColor;
}
#pragma mark - lazy -
- (NSView *)selectView//选中视图
{
    if (!_selectView) {
        _selectView = [[NSView alloc] init];
        _selectView.wantsLayer = YES;
        _selectView.layer.backgroundColor = NSColor.whiteColor.CGColor;
        [self addSubview:_selectView];
        [self addSubview:self.valueView positioned:NSWindowAbove relativeTo: _selectView];
    }
    return _selectView;
}
- (NSView *)unSelectView//未选中视图
{
    if (!_unSelectView) {
        _unSelectView = [[NSView alloc] init];
        _unSelectView.wantsLayer = YES;
        _unSelectView.layer.backgroundColor = NSColor.grayColor.CGColor;
        [self addSubview:_unSelectView];
    }
    return _unSelectView;
}
- (NSView *)cacheView//选中视图
{
    if (!_cacheView) {
        _cacheView = [[NSView alloc] init];
        _cacheView.wantsLayer = YES;
        _cacheView.layer.backgroundColor = NSColor.lightGrayColor.CGColor;
    }
    return _cacheView;
}
- (NSImageView *)valueView//选中视图
{
    if (!_valueView) {
        _valueView = [NSImageView imageViewWithImage:[NSImage imageNamed:NSImageNameTouchBarRecordStartTemplate]];
        _valueView.imageScaling = NSImageScaleAxesIndependently;
        _valueView.contentTintColor = NSColor.whiteColor;
        [self addSubview:_valueView];
    }
    return _valueView;
}
@end
  • 可以用鼠标拖动更改进度
  • 有缓存进度(使用是赋值就可以,不赋值不添加控件)
  • 内部使用的frame,但是外部也可以使用约束

有需要的小伙伴可以直接复制粘贴使用

完工

相关文章

网友评论

      本文标题:macOS开发之自定义Slider

      本文链接:https://www.haomeiwen.com/subject/aibbultx.html