hi hi,这是一篇来自新人的记录,欢迎讨论与指正!🤓
一、先贴效果
我将代码封装成类,在外部只要初始化这个类(如下图)就可以自定义出不同效果的段落式滑块;支持修改等分数量,自定义如演示中小圆点的样式(不限于圆点)👇
介绍下传入的参数🤨
- frame:字面意思(位置坐标和大小)
- equivalentDivisionCount:把滑块进行几等分
- maxLabelValue:slider的最大数值
- initialValue:初识化数值
- stepLength:分段图标的的宽度增加(为0时则等大)
- config:( [ UIView ], CGFloat)->():自定义分段图标(例子中规定了最后一个图标大小)
- valueCallback: ((Float) -> ()):回调获取随着slider滑动而改变的数值
二、卡壳的点
照着一般的思路,为了获取等分点的坐标位置,会想到先通过整个slider的width然后➗等分的数量,获取每一等分的宽度
fileprivate lazy var sliceWidth = slider.frame.width / CGFloat(equivalentDivisionCount)
然后问题发生了,主要就是分段图标的centerX坐标和thumb移动停止后的centerX坐标不一致,导致如下图的情况发生👇
我一开始以为是因为frame.origin.x与center.x没统一的问题,后来找了半天发现是原生控件本身存在一个偏移量
三、原因与解决
在我仔细看下图层结构后发现(贴出的图片可能不够清晰,文末附demo链接,可自行查看)😁
-
获取的sliceWidth是基于UISlider的width,但是thumb的坐标是基于slider中的子视图imageView,他两的width不一样👇
-
而且起始点和终点有偏移👇
- 基于slider中的子视图imageView计算出每等分的宽度sliceWidth,由上图可知
fileprivate lazy var sliceWidth = (slider.frame.width - thumbImageRadius * 2) / CGFloat(equivalentDivisionCount)
- 统一分段图标的起始点和thumb的起始点,由上图可知需要将第一个分段图标的centerX加上thumb Image(如果是自定义图片的话)的半径
view.center.x = sliceWidth * (i + 1) + thumbImageRadius
就成功解决啦🤌
四、后续的思考
为了完成目的,我将每个分段图标抽象成了一个点(center点),如果分段图标是等大的就没什么问题,但是如果它的半径会按步长不断增加的话,那么从视觉效果上,随着分段图标的增加,他们的距离会越来越近;如果将分段图标的半径也加入每等分长度换算的话,又会与一开始“等分”的初衷不同,因为slider输出的值将会不是等分。(当然也可以通过先通过等比例换算再输出数值的方法来解决,具体看需求了😀)
demo地址:github.com/JoyceHu-77/…