如何分三个阶段处理滑块?
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
,如果您认为可重用性是值得的。
UISlider
是 UIControl
的子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()
我在 iOS 应用程序中有一个 UISlider 对象,使用以下代码初始化。
theSlider = UISlider()
基本功能是可以的,但是我需要的是清楚的分别处理这三个事件:
- 用户开始移动滑块时的事件。
- 用户移动滑块时的事件。
- 用户停止移动滑块时的事件。
目前我使用这个代码:
theSlider.addTarget(self, action: #selector(sliderHandle(_:)),
for: .valueChanged)
并且处理第二个事件就可以了。 但是对于第一个和第三个,我想我需要在不确定的情况下继承 UISlider。欢迎任何提示。
作为一般注意事项,请务必检查 class 层次结构,例如小部件的超classes,以查看从它们继承的小部件还有哪些其他方法可用。
您不一定需要子class UISlider
,但您可能想要子class,或者,根据您的操作,UIControl
,如果您认为可重用性是值得的。
UISlider
是 UIControl
的子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()