如何跟踪值何时更改以及何时停止拖动?

Las*_*boy 3 events uislider ios swift

以UISlider的经验,我为ValueChanged事件创建IBAction 。现在,根据我的isContinuous设置,它会在值更改或拖动停止时触发。我的问题是我需要跟踪两种情况,但是我不能同时isContinuous设置两种方式。

有什么方法可以跟踪更改的值以及用户何时停止拖动?当值连续变化时,我想更新一个计数器,并且,当拖动停止时,我想刷新数据。我不想每次更改值时都刷新数据,因为这会导致过多的开销。我尝试了其他一些操作,但是在拖动停止时没有一个被调用。

Nor*_*ast 5

您尝试找到的解决方案的术语称为“反跳”。这样的想法是,您可以合并对同一方法的频繁调用,并且仅在调用停止一段时间后才执行该方法。当您快速接收大量用户输入并且必须对该输入执行相对繁重的工作时,去抖动是一种改善用户体验的好方法。只有在用户完成输入后才执行工作,才能避免CPU进行过多的工作并降低应用的运行速度。一些示例可能是在用户滚动页面时移动视图,在用户输入搜索词时更新表格视图或在一系列按钮点击后进行网络呼叫。

下图显示了一个示例,该示例显示了如何使用a UISlider来实现它。您可以将示例复制并粘贴到一个空的游乐场中进行尝试。

//: A UIKit based Playground for presenting user interface

import UIKit
import PlaygroundSupport

class MyViewController : UIViewController {

    // Timer to record the length of time between debounced calls
    var timer: Timer? = nil

    override func loadView() {
        super.loadView()

        let view = UIView()
        view.backgroundColor = .white

        // Set up the slider
        let slider = UISlider(frame: CGRect(x: 100, y: 100, width: 200, height: 50))
        slider.minimumValue = 0
        slider.maximumValue = 100
        slider.isContinuous = true
        slider.addTarget(self, action: #selector(sliderValueDidChange(_:)), for: .valueChanged)
        self.view.addSubview(slider)
    }

    @objc func sliderValueDidChange(_ sender: UISlider) {
        // Coalesce the calls until the slider valude has not changed for 0.2 seconds
        debounce(seconds: 0.2) {
            print("slider value: \(sender.value)")
        }
    }

    // Debounce function taking a time interval to wait before firing after user input has stopped
    // and a function to execute when debounce has stopped being called for a period of time.
    func debounce(seconds: TimeInterval, function: @escaping () -> Swift.Void ) {
        timer?.invalidate()
        timer = Timer.scheduledTimer(withTimeInterval: seconds, repeats: false, block: { _ in
            function()
        })
    }
}

// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
PlaygroundPage.current.needsIndefiniteExecution = true
Run Code Online (Sandbox Code Playgroud)

示例的内容是此函数:

func debounce(seconds: TimeInterval, function: @escaping () -> Swift.Void ) {
    timer?.invalidate()
    timer = Timer.scheduledTimer(withTimeInterval: seconds, repeats: false, block: { _ in
        function()
    })
}
Run Code Online (Sandbox Code Playgroud)

在这里,每次debounce调用都会使计时器无效,然后安排新的计时器来调用function传入的计时器。这确保function直到足够的时间未使计时器无效之前,才调用。