我有UITextField用于输入搜索字符串,UITableView用于输入结果。 我想要的是当用户输入超过3个字母时运行搜索功能,并且自从最后一个符号添加到UITextView后至少经过了0.5秒。
我找到了(Detect when user stopped / paused typing in Swift)函数,我把它添加到我的ViewController中,它有类SearchVC和方法server_search
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
NSObject.cancelPreviousPerformRequests(
withTarget: self,
selector: #selector(SearchVC.server_search),
object: textField)
self.perform(
#selector(SearchVC.server_search),
with: textField,
afterDelay: 0.5)
return true
}
但没有任何反应。
答案 0 :(得分:6)
您可以使用Timer
...
var timer: Timer?
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
timer?.invalidate() // Cancel any previous timer
// If the textField contains at least 3 characters…
let currentText = textField.text ?? ""
if (currentText as NSString).replacingCharacters(in: range, with: string).characters.count >= 3 {
// …schedule a timer for 0.5 seconds
timer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(performSearch()), userInfo: nil, repeats: false)
}
return true
}
func performSearch() {
}
并且不要忘记将视图控制器设置为UITextField
delegate
答案 1 :(得分:2)
定时器的使用有一些优点。根据您的实施,您将取消 所有为你的对象执行的操作,这可能会失控。
相反,计时器可让您对其进行细粒度控制。请参阅以下实现:
var searchTimer: Timer?
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
// Invalidate remove the previous timer, since it's optional if the previous timer is already cancelled or nil, it won't affect execution
searchTimer?.invalidate()
searchTimer = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false, block: { (timer) in
//do Something crazy
self.server_search()
})
return true
}
答案 2 :(得分:1)
虽然使用import numpy as np
def moving_average(a, n=3) :
ret = np.cumsum(a, dtype=float)
ret[n:] = ret[n:] - ret[:-n]
return ret[n - 1:] / n
仍然是有效的答案,但是从Swift 3开始,您可以使用Timer
…
DispatchWorkItem