HTML文本域添加滑杆,Objective-C 自定义UISlider滑杆 分段样式

写在前面

弄了下个人站...防止内容再次被锁定...所有东西都在这里面

welcome~

个人博客

效果

自定义一个功能简单的分段的滑杆 可显示分段名

为了显示效果,我们将滑块和节点都设置为不规则

这里只实现了分段的slider,未分段的没有实现,有兴趣的可以定义另一种类型做个判断修改下

baa1b7454ee3

效果.gif

需求分析

我们需要的是一个可分段slider

主要元素有

滑杆视图

滑杆上的节点

节点名称

当前滑块

由于要设定节点和滑块的frame,size又是可变的,最死脑细胞的就是滑块和节点frame的计算了!!!!

代码部分

查看UISlider控件发现这个类是继承自UIControl,那么就自定义一个UIControl来实现UISlider没有的效果。

公开的变量中都是一些通用的参数,无非就是颜色、图片之类的,我这里使用比较少,有兴趣的可以自行添加。

公开变量

#import

@interface CustomSlider : UIControl

//当前值

@property (nonatomic,assign)NSInteger value;

//选择点个数 >2

@property (nonatomic,assign)NSInteger numberOfPart;

//当前滑块图片

@property (nonatomic,strong)UIImage *thumbImage;

//当前滑块尺寸

@property (nonatomic,assign)CGSize thumbSize;

//分段点尺寸

@property (nonatomic,assign)CGSize partSize;

//slider height

@property (nonatomic,assign)CGFloat sliderBarHeight;

//分段名

@property (nonatomic,strong)NSArray *partNameArray;

//分段名偏移位置 初始在slider上

@property (nonatomic,assign)CGPoint partNameOffset;

@end

设置非公开的全局变量

@interface CustomSlider()

@property(nonatomic,assign)CGRect thumbRect; //滑块fram

@property(nonatomic,assign)CGRect sliderRect; //sliderFrame

@property(nonatomic,strong)NSMutableArray *partRectArray; //节点frame数组

@property(nonatomic,assign)BOOL isFirst; //首次运行

@property(nonatomic,strong)NSDictionary *textAttributesDict;//文本字体信息

@end

一些初始化

- (instancetype)initWithFrame:(CGRect)frame {

self = [super initWithFrame:frame];

if (self) {

self.partRectArray = [NSMutableArray array];

self.numberOfPart = 2;

self.sliderBarHeight = 20;

self.thumbSize = CGSizeMake(self.sliderBarHeight, self.sliderBarHeight);

self.partNameOffset = CGPointZero;

self.partSize = self.thumbSize;

}

return self;

}

设置一个set方法

//节点必须>1

- (void)setNumberOfPart:(NSInteger)numberOfPart {

_numberOfPart = numberOfPart > 1 ? numberOfPart: 2;

}

设置文本属性,用于绘制文字

//设置文本属性

- (NSDictionary*)textAttributesDict {

if (!_textAttributesDict) {

NSMutableDictionary *dict = [NSMutableDictionary dictionary];

dict[NSForegroundColorAttributeName] = [UIColor blackColor]; // 文字颜色

dict[NSFontAttributeName] = [UIFont systemFontOfSize:14]; // 字体

_textAttributesDict = dict;

}

return _textAttributesDict;

}

重绘主要是画带节点的slider和滑块

//重绘

- (void)drawRect:(CGRect)rect {

CGContextRef context = UIGraphicsGetCurrentContext();

//画slider

[self loadSliderWithContext:context];

//画滑块

[self loadThumWithContext:context];

}

//画滑块

- (void)loadThumWithContext:(CGContextRef)context {

//当前滑块

if (!self.isFirst) {

//滑块初始化

self.thumbRect = [self.partRectArray[0] CGRectValue];

self.isFirst = YES;

}

//有背景图则用背景图 没有就画圆

if (self.thumbImage) {

[self.thumbImage drawInRect: self.thumbRect];

} else {

CGContextAddEllipseInRect(context, self.thumbRect);

[[UIColor blueColor] set];

CGContextFillPath(context);

}

}

//画滑杆内容

- (void)loadSliderWithContext:(CGContextRef)context {

//设置滑杆的frame

CGFloat tmp = self.thumbSize.width > self.partSize.width ? self.thumbSize.width : self.partSize.width;

CGFloat tmpHeight = self.thumbSize.height > self.partSize.height ? self.thumbSize.height : self.partSize.height;

CGFloat sliderHeight = self.sliderBarHeight;

CGFloat sliderMargin = sliderHeight/2 + tmp/2;

CGFloat sliderY = CGRectGetHeight(self.frame)/2;

CGFloat sliderWidth = CGRectGetWidth(self.frame) - 2 * sliderMargin - tmp;

self.sliderRect = CGRectMake(sliderMargin + self.partSize.width/2, sliderY-tmpHeight/2, sliderWidth+tmp, tmpHeight);

//画slider滑杆

CGPoint starPoint = CGPointMake(sliderMargin + tmp/2, sliderY);

CGPoint endPoint = CGPointMake(CGRectGetWidth(self.frame)-sliderMargin- tmp/2, sliderY);

CGContextMoveToPoint(context, starPoint.x, starPoint.y);

CGContextAddLineToPoint(context, endPoint.x, endPoint.y);

CGContextSetLineWidth(context, sliderHeight); // 线的宽度

CGContextSetLineCap(context, kCGLineCapRound); // 起点和重点圆角

CGContextSetStrokeColorWithColor(context, [UIColor greenColor].CGColor);

CGContextStrokePath(context);

//画分段点

CGFloat partPointWidth = self.partSize.width;

CGFloat partPointHeight = self.partSize.height;

CGFloat y = CGRectGetHeight(self.frame)/2 - self.partSize.height/2;

[self.partRectArray removeAllObjects];

for (int i = 0; i < self.numberOfPart; i++) {

CGFloat x = i * sliderWidth/(self.numberOfPart-1) + starPoint.x-partPointWidth/2 ;

CGContextAddEllipseInRect(context, CGRectMake(x, y, partPointWidth, partPointHeight));

[[UIColor blackColor] set];

CGContextFillPath(context);

//计算滑块位置

CGRect fram = CGRectMake(x+partPointWidth/2-self.thumbSize.width/2, y+partPointHeight/2-self.thumbSize.height/2, self.thumbSize.width, self.thumbSize.height);

[self.partRectArray addObject:[NSValue valueWithCGRect:fram]];

}

//画分段点名称

for (int i = 0; i < self.partNameArray.count; i++) {

NSString *partName = self.partNameArray[i];

CGRect parRect = [self.partRectArray[i] CGRectValue];

//根据字体属性 计算出size

CGSize size = [partName sizeWithAttributes:self.textAttributesDict];

CGFloat nameX = parRect.origin.x + parRect.size.width/2 - size.width/2 + self.partNameOffset.x;

CGFloat nameY = parRect.origin.y + self.partNameOffset.y;

CGRect nameFrame = CGRectMake(nameX, nameY, size.width, size.height) ;

[partName drawInRect:nameFrame withAttributes:self.textAttributesDict];

}

}

最后设置拖动滑块和滑块最后停留的位置

//开始拖动

- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(nullable UIEvent *)event {

CGPoint point = [touch locationInView:self];

//可滑动范围

if (!CGRectContainsPoint(self.sliderRect, point)) {

return NO;

}

int index = [self getCurrentXWithOffset:point.x];

self.thumbRect = [self.partRectArray[index] CGRectValue];

[self setNeedsDisplay];

return YES;

}

//持续拖动

- (BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(nullable UIEvent *)event {

CGPoint point = [touch locationInView:self];

CGFloat thumbImageX = point.x - self.thumbSize.width/2;

self.thumbRect = CGRectMake(thumbImageX, self.thumbRect.origin.y, self.thumbRect.size.width, self.thumbRect.size.height);

[self setNeedsDisplay];

return YES;

}

//拖动结束

- (void)endTrackingWithTouch:(nullable UITouch *)touch withEvent:(nullable UIEvent *)event {

CGPoint point = [touch locationInView:self];

int index = [self getCurrentXWithOffset:point.x];

self.thumbRect = [self.partRectArray[index] CGRectValue];

[self setNeedsDisplay];

NSLog(@"point = %f",point.x);

//增加控制事件

[self sendActionsForControlEvents:UIControlEventValueChanged];

}

//计算滑到一半时根据占比选择对应位置

- (int)getCurrentXWithOffset:(CGFloat)x {

CGFloat tmpX = x - [self.partRectArray[0] CGRectValue].origin.x;

//超出边界

if (tmpX > [self.partRectArray[self.numberOfPart-1] CGRectValue].origin.x) {

tmpX = [self.partRectArray[self.numberOfPart-1] CGRectValue].origin.x;

}

//计算总长度

CGFloat firstx = [[self.partRectArray firstObject] CGRectValue].origin.x;

CGFloat lastx = [[self.partRectArray lastObject] CGRectValue].origin.x;

CGFloat wid = lastx - firstx;

CGFloat part = wid/(self.numberOfPart-1) ;

//减去滑块占比

CGFloat per = self.thumbSize.width/2/part;

int count = tmpX / part - per + 0.5;

self.value = count;

return count;

}

写的思路比较简单,就是计算frame很伤。

滑块可以设定为图片。

当然slider背景也可以设置成图片,这个我没写进去,相信也是很好修改的。

DEMO地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值