ios:利用Slider实现刻度尺效果

2022-12-16  本文已影响0人  xing_x

需求:实现一个带刻度尺的滑竿UI

实现方案:重写Slider

利用画布原理,重绘画布上的UI,添加刻度尺的方法,实现滑竿UI,并且展示滑竿的值,可以自定义刻度尺的颜色,背景色,字体大小,可以用图片显示刻度尺。


Untitled.gif
具体实现逻辑代码:
//  WSSlider.m
//  BtnDemo
//
//  Created by zzialx on 2022/9/28.
//

#import "WSSlider.h"

#define DEFAULT_BAR_W           4.0

#define DEFAULT_BAR_H           12.0

#define DEFAULT_BAR_CLO         [UIColor lightGrayColor]

#define DEFAULT_BAR_RADIUS      0.0

#define DEFAULT_RULE_BAR_CLO    [UIColor redColor]

#define DEFAULT_RULE_BAR_W      4.0

#define DEFAULT_RULE_BAR_H      12.0

#define DEFAULT_FONT            [UIFont systemFontOfSize:13.0]

#define DEFAULT_RULE_SIZE       CGSizeMake(100, 20)


@interface WSSlider ()

@property(nonatomic,strong)UIView * markContentView;

/**
 滑竿值label
 */
@property(nonatomic,strong)UILabel * sliderValueLab;

@end

@implementation WSSlider

- (instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self){
        self.markPositions = @[];
        self.barWidth = DEFAULT_BAR_W;
        self.barHeight = DEFAULT_BAR_H;
        self.barColor = DEFAULT_BAR_CLO;
        self.barRadius = DEFAULT_BAR_RADIUS;
        self.barIamge = [UIImage imageNamed:@""];
        self.showRuleBarVaule = YES;
        self.ruleBarVaueColor = DEFAULT_RULE_BAR_CLO;
        self.ruleBarWidth = DEFAULT_RULE_BAR_W;
        self.ruleBarHeight = DEFAULT_RULE_BAR_H;
        self.ruleBarFont = DEFAULT_FONT;
        self.showSliderValue = YES;
        self.sliderValueFont = DEFAULT_FONT;
        self.sliderValueClolor = DEFAULT_RULE_BAR_CLO;
        self.sliderValueSize = DEFAULT_RULE_SIZE;
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    if (_markContentView != nil) {
        [_markContentView removeFromSuperview];
    }
    _markContentView = [[UIView alloc] initWithFrame:rect];
    _markContentView.backgroundColor = UIColor.clearColor;
    _markContentView.userInteractionEnabled = NO;
    NSArray * trackViews = self.subviews;
    UIView * minimumTrackView = trackViews.lastObject;
    if(minimumTrackView == nil){
        [_markContentView insertSubview:self aboveSubview:minimumTrackView];
    }else{
        [self addSubview:_markContentView];
    }
    CGRect trackFrame = [self trackRectForBounds:rect];
    for (int i = 0; i<self.markPositions.count; i++) {
        CGFloat markValue = [self.markPositions[i] floatValue];
        CGRect thumbFrame = [self thumbRectForBounds:rect trackRect:trackFrame value:markValue];
        MarkStyle  style = self.markStyle;
        switch (style) {
            case MarkStyleShape:{
                CGFloat midX = CGRectGetMidX(thumbFrame);
                CGFloat midY = CGRectGetMidY(thumbFrame);
                CGRect markRect =  CGRectMake(midX, midY-self.barHeight, self.barWidth, self.barHeight);
                UIView * markView = [[UIView alloc]initWithFrame: markRect];
                markView.layer.masksToBounds = YES;
                markView.layer.cornerRadius = self.barRadius;
                ////                markView.backgroundColor = markValue > value ? maximumMarkTintColor : minimumMarkTintColor
                markView.backgroundColor = self.barColor;
                [_markContentView addSubview:markView];
                
                if(self.showRuleBarVaule){
                    CGRect barValueRect =  CGRectMake(midX - self.ruleBarWidth, midY, self.ruleBarWidth * 2, self.ruleBarHeight * 2);
                    UILabel * barVauleLab = [[UILabel alloc]initWithFrame: barValueRect];
                    barVauleLab.textAlignment = NSTextAlignmentCenter;
                    barVauleLab.font = self.ruleBarFont;
                    barVauleLab.textColor = self.ruleBarVaueColor;
                    barVauleLab.text = [NSString stringWithFormat:@"%d",(int)markValue];
                    [_markContentView addSubview:barVauleLab];
                }
            }
                break;
            case MarkStyleImage:{
                CGRect markRect = CGRectMake(CGRectGetMidX(thumbFrame), CGRectGetMidY(thumbFrame), self.barWidth, self.barHeight);
                UIImageView * markView = [[UIImageView alloc]initWithFrame:markRect];
                markView.image = self.barIamge;
                markView.tintColor = UIColor.purpleColor;
                [_markContentView addSubview:markView];
            }

                break;
            default:
                break;
        }
    }
    if(self.showSliderValue){
        [_markContentView addSubview:self.sliderValueLab];
    }
}
#pragma mark - # Private Method self
- (void)layoutSubviews{
    [super layoutSubviews];
    [self p_updateSliderFrame];
}
- (void)p_updateSliderFrame{
    if (!self.showSliderValue) {
        return;
    }
    if (self.value) {
        _sliderValueLab.hidden = NO;
    } else {
        _sliderValueLab.hidden = YES;
    }
    CGRect thumbRect = [self thumbRectForBounds:self.bounds
                                      trackRect:[self trackRectForBounds:self.bounds]
                                          value:self.value];
    CGFloat thumbW = thumbRect.size.width;
    CGFloat thumbH = thumbRect.size.height;
    NSString *memo = [self.sliderValueNumericalUnit length] > 0 ? self.sliderValueNumericalUnit : @"";
    [_sliderValueLab setText:[NSString stringWithFormat:@"%lf %@",self.value,memo]];
    CGSize valueSize = self.sliderValueSize;
    CGRect labelRect = CGRectInset(thumbRect, (thumbW - valueSize.width)/2, (thumbH - valueSize.height)/2);
    labelRect.origin.y = thumbRect.origin.y -  valueSize.height * 2;
    [_sliderValueLab setFrame:labelRect];
}

#pragma mark - # lazy load

- (UILabel*)sliderValueLab{
    if(!_sliderValueLab){
        _sliderValueLab = [[UILabel alloc]initWithFrame:CGRectZero];
        [_markContentView addSubview:_sliderValueLab];
        _sliderValueLab.font = self.sliderValueFont;
        _sliderValueLab.textColor = self.sliderValueClolor;
        _sliderValueLab.textAlignment = NSTextAlignmentCenter;
    }
    return _sliderValueLab;
}

@end
WSSlider.h类的实现
//
//  WSSlider.h
//  BtnDemo
//
//  Created by zzilx on 2022/9/28.
//

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

typedef enum : NSUInteger {
    MarkStyleShape,///<默认样式
    MarkStyleImage,///<图片样式
} MarkStyle;

@interface WSSlider : UISlider
/**
 刻度样式
 */
@property(nonatomic,assign)MarkStyle  markStyle;
/**
 刻度数组
 */
@property(nonatomic,strong)NSArray * markPositions;

/**
 刻度颜色 默认灰色
 */
@property(nonatomic,strong)UIColor * barColor;

/**
 刻度高度 默认为12.0
 */
@property(nonatomic,assign)CGFloat barHeight;

/**
 刻度宽度 默认为4.0
 */
@property(nonatomic,assign)CGFloat barWidth;

/**
 刻度圆角 默认为0
 */
@property(nonatomic,assign)CGFloat barRadius;

/**
 刻度图片 默认图
 */
@property(nonatomic,strong)UIImage * barIamge;

/**
 是否显示刻度尺数字 YES代表显示,默认显示
 */
@property(nonatomic,assign)BOOL showRuleBarVaule;

/**
 刻度尺数字颜色值,默认是红色
 */
@property(nonatomic,strong)UIColor * ruleBarVaueColor;

/**
 刻度尺数字宽度,默认4.0
 */
@property(nonatomic,assign)CGFloat ruleBarWidth;

/**
 刻度尺数字高度,默认12.0
 */
@property(nonatomic,assign)CGFloat ruleBarHeight;


/**
 刻度尺数字文字显示大小,默认13号字体
 */
@property(nonatomic,strong)UIFont * ruleBarFont;

/**
 是否实时显示值(刻度尺上方)(默认显示)YES
 */
@property(nonatomic,assign)BOOL showSliderValue;

/**
 滑竿值文本大小 默认13号字体
 */
@property(nonatomic,strong)UIFont * sliderValueFont;
/**
 滑竿值文本颜色,默认红色
 */
@property(nonatomic,strong)UIColor * sliderValueClolor;

/**
 滑竿值显示单位
 */
@property(nonatomic,strong)NSString * sliderValueNumericalUnit;

/**
 滑竿显示框大小(默认size 100,20)
 */
@property(nonatomic,assign)CGSize   sliderValueSize;

@end

NS_ASSUME_NONNULL_END

#####动态效果:
[图片上传中...(4181671260359_.pic.jpg-615f4e-1671260471047-0)]

使用方法:
```self.slider = [[WSSlider alloc]initWithFrame:CGRectMake(15, 300, self.view.frame.size.width-30, 50)];
    [self.view addSubview:self.slider];
    self.slider.maximumValue = 5;
    self.slider.minimumValue = 0;
    self.slider.thumbTintColor = [UIColor redColor];
    self.slider.maximumTrackTintColor = [UIColor lightGrayColor];
    self.slider.minimumTrackTintColor = [UIColor blueColor];
    self.slider.barHeight = 12.0;
    self.slider.barWidth = 2.0;
    self.slider.markPositions = @[@0,@1,@2,@3,@4,@5];
    self.slider.sliderValueNumericalUnit = @"公里";
简单实用
上一篇 下一篇

猜你喜欢

热点阅读