如何防止 UISlider 在捕捉/步进时跳到位

Posted

技术标签:

【中文标题】如何防止 UISlider 在捕捉/步进时跳到位【英文标题】:How to prevent UISlider from jumping into place while snapping/stepping 【发布时间】:2018-10-24 16:01:21 【问题描述】:

我有一个 UISlider 可以捕捉到 5 个不同的位置。

slider.minimumValue = 1
slider.maximumValue = 5

捕捉效果很好,但它很突然并且不能顺利捕捉到位。它有点“跳跃”到位

我尝试为滚动设置动画(没有用):

@objc func onSliderValChanged(_ sender: UISlider) 
    UIView.animate(withDuration: 0.5) 
        self.slider.value = round(sender.value)
        self.slider.setValue(round(sender.value), animated: true)
    

我也尝试添加 panGesture(没用):

panGesture = UIPanGestureRecognizer(target: self, action: #selector(panGestureHandler(_:)))
slider.addGestureRecognizer(panGesture)

@objc func panGestureHandler(_ recognizer: UIPanGestureRecognizer)

    let currentPoint = recognizer.location(in: slider)
    let percentage = currentPoint.x/slider.bounds.size.width

    let delta = Float(percentage) * (slider.maximumValue - slider.minimumValue)
    let value = slider.minimumValue + delta
    slider.setValue(round(value), animated: true)

如何实现滑块平滑滚动但仍卡入到位?

这是没有上述尝试的原始代码:

let slider: UISlider = 
    let slider = UISlider()
    slider.translatesAutoresizingMaskIntoConstraints = false
    slider.minimumValue = 1
    slider.maximumValue = 5
    slider.value = 3
    slider.isContinuous = true
    slider.addTarget(self, action: #selector(onSliderValChanged(_:)), for: .valueChanged)
    return slider
()

@objc func onSliderValChanged(_ sender: UISlider) 

    slider.value = round(sender.value)


func setAnchors() 
    slider.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 0).isActive = true
    slider.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 10).isActive = true
    slider.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -10).isActive = true

【问题讨论】:

【参考方案1】:

UISlider 使用多个 UIImageView 子视图绘制自己。当您更改滑块的value 时,滑块会发送自己的setNeedsLayout,但它实际上并不会更改其子视图的帧,直到它在运行循环的布局阶段收到layoutSubviews

要对值的变化进行动画处理,您需要使滑块在动画块内布置其子视图。因此:

@IBAction func sliderValueChanged(_ slider: UISlider) 
    slider.value = round(slider.value)
    UIView.animate(withDuration: 0.2, animations: 
        slider.layoutIfNeeded()
    )

【讨论】:

你怎么知道选择数字 0.2?我尝试了其他数字,效果最好 只是体验。 0.25 也能很好地工作,这就是我的应用程序的滑块步骤/快照的结果。尽可能尝试。和平

以上是关于如何防止 UISlider 在捕捉/步进时跳到位的主要内容,如果未能解决你的问题,请参考以下文章

将 UISlider 捕捉到最近的数组值

实施步骤/捕捉 UISlider

Swift:将 UISlider 捕捉到最接近的值

如何使用步进滑块在滑块拇指上添加 UILabel?

React / Tailwind:如何保持动画到位以防止布局错误?

自定义 UISlider 不会结束