根据我使用 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/