如何分三个阶段处理滑块?

How to handle a slider in 3 phases?

我在 iOS 应用程序中有一个 UISlider 对象,使用以下代码初始化。

theSlider = UISlider()

基本功能是可以的,但是我需要的是清楚的分别处理这三个事件:

目前我使用这个代码:

theSlider.addTarget(self, action: #selector(sliderHandle(_:)), 
                    for: .valueChanged)

并且处理第二个事件就可以了。 但是对于第一个和第三个,我想我需要在不确定的情况下继承 UISlider。欢迎任何提示。

作为一般注意事项,请务必检查 class 层次结构,例如小部件的超classes,以查看从它们继承的小部件还有哪些其他方法可用。

您不一定需要子class UISlider,但您可能想要子class,或者,根据您的操作,UIControl,如果您认为可重用性是值得的。

UISliderUIControl 的子class,是 UIView 的子class。 UIControl 是 'widgetized' UIView,换句话说,就其提供的方法而言,主要是促进用户输入的检测,并支持发送事件,这些功能往往对任何UI 控制小部件。

对于移动和位置检测,UIControl class 有方法 beginTracking()continueTracking()endTracking()cancelTracking()isTracking()isTouchInside()。这些可以直接从 UISlider 对象获得。

同样,您可以使用 sendAction()sendActions() 显式触发操作(事件),UIControl 使 public 隐含地可供 UISlider 使用。

如果您不需要 subclass,您可以编写一段 "one-off"(例如特定于应用程序的)代码,直接通过您的 UISlider 使用上述方法例如,直接将 'touches' 跟踪到小部件并在滑动路径的关键位置传递事件,或者使用您检测到的特定行为。

查看此问题,"IPhone: How to detect end of slider drag" 了解实施思路。

Apple 的 UIControl documentation 有一个子class 注释部分解释如何使用目标-动作机制。

UIControl.Event除了.valueChanged还有很多其他的值。 .touchDown 可以告诉您用户何时开始与滑块交互,. touchUpInside.touchUpOutside 可以告诉您用户何时完成拖动。这是一个游乐场示例:

import SwiftUI
import PlaygroundSupport

class V: UIViewController {
  let slider = UISlider(frame: .init(origin: .zero, size: .init(width: 200, height: 50)))
  override func viewDidLoad() {
    super.viewDidLoad()
    slider.minimumValue = 0
    slider.maximumValue = 100
    slider.value = 50
    slider.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(slider)
    slider.addTarget(self, action: #selector(changed), for: .valueChanged)
    slider.addTarget(self, action: #selector(began), for: .touchDown)
    slider.addTarget(self, action: #selector(ended), for: .touchUpInside)
    slider.addTarget(self, action: #selector(ended), for: .touchUpOutside)
  }
  @objc private func changed(sender: UISlider) {
    print("Changed")
  }
  @objc private func began(sender: UISlider) {
    print("Began")
  }
  @objc private func ended(sender: UISlider) {
    print("Ended")
  }
}
PlaygroundPage.current.liveView = V()