Термин для решения, которое вы пытаетесь найти, называется «Debouncing».Идея состоит в том, что вы объединяете частые вызовы одного и того же метода и выполняете метод только после того, как вызовы прекратились в течение определенного периода времени.Debouncing - отличный способ улучшить пользовательский опыт, когда вы быстро принимаете большую часть пользовательского ввода и должны выполнять относительно большую нагрузку на этот ввод.Выполнение работы только после того, как пользователь завершил ввод, спасает процессор от чрезмерной работы и замедляет работу приложения.В некоторых примерах можно перемещать представление, когда пользователь прокручивает страницу, обновлять представление таблицы, когда пользователь вводит поисковый запрос, или совершать сетевые вызовы после серии нажатий кнопок.
Пример, показывающий, как его можно реализовать.с 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
Суть примера в следующем:
func debounce(seconds: TimeInterval, function: @escaping () -> Swift.Void ) {
timer?.invalidate()
timer = Timer.scheduledTimer(withTimeInterval: seconds, repeats: false, block: { _ in
function()
})
}
Здесь каждый раз debounce
вызывается, делает недействительным таймер и затем планирует новый таймер для вызова переданного function
. Это гарантирует, что function
не вызывается до тех пор, пока не пройдет достаточно времени, чтобы не сделать таймер недействительным.