您尝试找到的解决方案的术语称为“反跳”。这样的想法是,您可以合并对同一方法的频繁调用,并且仅在调用停止一段时间后才执行该方法。当您快速接收大量用户输入并且必须对该输入执行相对繁重的工作时,去抖动是一种改善用户体验的好方法。只有在用户完成输入后才执行工作,才能避免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直到足够的时间未使计时器无效之前,才调用。
| 归档时间: |
|
| 查看次数: |
496 次 |
| 最近记录: |