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 = @"公里";
简单实用