【问题标题】:How to handle a slider in 3 phases?如何分三个阶段处理滑块?
【发布时间】:2020-01-07 21:46:59
【问题描述】:

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

theSlider = UISlider()

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

  • 用户开始移动滑块时的事件。
  • 用户要移动滑块的事件。
  • 用户停止移动滑块时的事件。

目前我使用这个代码:

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

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

【问题讨论】:

    标签: ios swift uislider


    【解决方案1】:

    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()
    

    【讨论】:

      【解决方案2】:

      作为一般说明,请务必检查类层次结构,例如小部件的超类,查看从它们继承的小部件还有哪些其他方法可用。

      您不一定需要子类化 UISlider,但您可能想要子类化它,或者,根据您正在做的事情,UIControl,如果您认为可重用是值得的。

      UISlider 是UIControl 的子类,UIView 是UIView 的子类。 UIControl 是一个“小部件化”UIView,换句话说,只要它提供的方法主要有助于检测用户输入,并支持发送事件,这些功能往往对于任何 UI 控件小部件都是通用的。

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

      同样,您可以使用sendAction() 和sendActions() 显式触发操作(事件),由UIControl 公开,因此UISlider 可以隐式使用。

      如果您不需要子类化,您可以编写一段“一次性”(例如特定于应用程序)的代码,以直接通过您的 UISlider 实例利用上述方法,直接跟踪“触摸”以小部件并在幻灯片路径的关键位置或您检测到的特定行为处传递事件。

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-19
        相关资源
        最近更新 更多