简约同样简单:为UISlider添加显示当前值的标签(上)

版权声明:大熊猫猪·侯佩原创或翻译作品.谢绝转载! hopy https://blog.csdn.net/mydo/article/details/86663910

本文畅想了几种为UISlider添加显示当前值的方法,并选择了其中一个稳定,简单的实现.适合iOS刚入门或中级水平的童鞋们观赏.

看不见值?这不科学!

默认的UISlider,你可以任意拖动,却看不见当前表示的值…

有点盲人摸象的赶脚了…

我们一般的做法是用另一个控件表示其当前值,比如一个UILabel.

不过这样貌似要另外占用一些空间,不紧凑!

看到UISlider上面那个圆圆的把手了么?我们准备把当前值显示在它里面!

几种可能的实现

  • 第一种: UISlider可以替换把手图片,如果我们可以用其当前表示的值生成对应的图片,我们就可以做到动态替换;因为这是Cocoa自带的接口,所以很稳定,唯一缺点是动态生成图片略显繁琐.
  • 第二种: 在运行时找到UISlider把手对应的View,将Label作为它的子视图;这样做的好处是一旦添加Label,它会随把手一起移动,你将不用再操心它的位置.但如何找到,以及何时去找到UISlider对应的View,需要一些小手段.
  • 第三种: 在UISlider的valueChanged回调中,根据当前值来计算Label位置.不过这样的话UISlider.isContinuous必须为true,因为你需要即时得到值的变化.

貌似选择很多啊,那我们选择哪一种呢?

答案是:上面统统都不选!

在这里插入图片描述
因为还有一种方法:方法零!

第零种方法

为了利用Cocoa的接口(稳定),为了UISlider.isContinuous可以为false,必须找到一种方法:如何定位Slider把手的位置?

其实这很简单!!!

因为UISlider本身自带thumbRect(…)方法,可以随时取得把手Rect的值.

所以我们赶快写一个短小精悍的方法来实现它:

private func thumbRectInView(slider:UISlider)->CGRect{
    let trackRect = slider.trackRect(forBounds: slider.bounds)
    let thumbRect = slider.thumbRect(forBounds: slider.bounds, trackRect: trackRect, value: slider.value)
    return view.convert(thumbRect, from: slider)
}

首先我们取得UISlider轨迹条Rect的值,然后利用它获取到把手Rect的值.接着我们将其转换为view中的坐标.

因为我们的Label实际是直接放在view里的.

我们还需要一个方法来显示UISlider当前表示的值,这个很容易:

private func updateThumbLbl(value:Float,center:CGPoint){
    sliderMarkLbl.center = center
    let ftValue = String(format: "%.1f", value)
    sliderMarkLbl.text = "\(ftValue)"
}

上面显示的值只保留1位小数,因为太长Label里也显示不下.

现在只剩下一个问题需要解决:如何监控UISlider把手的滑动?

最后一步

所幸的是,UIControl有这样一个事件: .touchDragInside

我们只需Hook它即可监听把手的拖动操作:

slider.addTarget(self, action: #selector(dragged(_:)), for: .touchDragInside)

@objc func dragged(_ sender:UISlider){
    let rectInView = thumbRectInView(slider: sender)
    let center = CGPoint(x: rectInView.midX, y: rectInView.midY)
    updateThumbLbl(value: sender.value, center: center)
}

不过光是这样还不够,因为有时用户点击把手时会造成其小范围的移动,这种移动并不会产生.touchDragInside事件,所以我们还得Hook另一个事件:

slider.addTarget(self, action: #selector(dragged(_:)), for: .touchDown)

好啦,原理就是这样,下面是实际运行效果:

在这里插入图片描述

结尾

利用Cocoa中UISlider的标准接口,我们扩展了它的行为,为其增加了即时值的显示.

如果大家有兴趣也可以自行实现一下上面给出的另外3种方法,相信这样你会收获更多.

不过还有其他更简单,更易于维护的方法吗?

重构大法好啊!

在这里插入图片描述

在下篇中我们尝试从另一种角度来实现本篇的内容,不过更简单,更易于维护!

感谢观赏,下篇见! 😃

下篇在此: 简约同样简单:为UISlider添加显示当前值的标签(下)

没有更多推荐了,返回首页