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

标签 ios swift events uislider

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

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

最佳答案

您试图找到的解决方案的术语称为“去抖动”。这个想法是,您合并对同一方法的频繁调用,并且仅在调用停止一段时间后才执行该方法。当您快速接收大量用户输入并且必须对该输入执行相对繁重的工作负载时,去抖动是改善用户体验的好方法。仅在用户完成输入时才执行工作可以避免 cpu 做太多工作并减慢应用程序的速度。一些示例可能是在用户滚动页面时移动 View ,在用户输入搜索词时更新 TableView 或在一系列按钮点击后进行网络调用。

下面的 playground 中显示了一个示例,展示了如何使用 UISlider 实现它。您可以将示例复制并粘贴到空的 playground 中进行尝试。

//: 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

这个例子的核心是这个函数:

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

每次调用 debounce 时,它都会使计时器无效,然后安排一个新计时器来调用传入的 function。这确保了 function 直到经过足够的时间不会让计时器失效后才会被调用。

关于ios - 如何跟踪值何时更改以及拖动何时停止?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50419415/

相关文章:

javascript - 使用 $(document).click 后 jQuery 函数不起作用

ios - React-Native ScrollView 在 setState 上丢失了位置

ios 以编程方式更改约束

ios - "Could not build module ' map 套件 '"

swift - 如何在 xcode 的 Playground 中导入 RxSwift?

javascript - 基本 Window.alert 功能在 Meteor 中不起作用

ios - CoreData 自定义 NSMappingModel 不迁移数据

swift - 如何在 SceneKit 中实现逼真的景深效果?

ios - 使用数组中的字符串淡入/淡出标签

c# - Bing map Windows Phone 上的图钉数量未知。我如何为他们每个人创建一个事件?