swift自定义等分段落式滑块(踩坑:thumb偏移量)

1,208 阅读2分钟

hi hi,这是一篇来自新人的记录,欢迎讨论与指正!🤓

一、先贴效果

gif1.gif

我将代码封装成类,在外部只要初始化这个类(如下图)就可以自定义出不同效果的段落式滑块;支持修改等分数量,自定义如演示中小圆点的样式(不限于圆点)👇

截屏2021-09-21 下午10.45.59.png

介绍下传入的参数🤨

  • 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坐标不一致,导致如下图的情况发生👇

gif2.gif

我一开始以为是因为frame.origin.x与center.x没统一的问题,后来找了半天发现是原生控件本身存在一个偏移量

三、原因与解决

在我仔细看下图层结构后发现(贴出的图片可能不够清晰,文末附demo链接,可自行查看)😁

  • 获取的sliceWidth是基于UISlider的width,但是thumb的坐标是基于slider中的子视图imageView,他两的width不一样👇 截屏2021-09-16 上午12.41.30.JPG

  • 而且起始点和终点有偏移👇

截屏2021-09-16 上午12.42.12.JPG

截屏2021-09-16 上午12.43.07 2.jpg

  • 基于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/…