I've dug around stackoverflow and found the solution which I converted to Swift, it doesn't seem to work and the selector is still being performed.
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
self.filter.searchTerm = self.searchBar.text
NSObject.cancelPreviousPerformRequestsWithTarget(self, selector: "getHints", object: nil)
NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "getHints", userInfo: nil, repeats: false)
}
Is there a better way to do this in swift? Thanks!
UPDATE 2016/09/01:
We can use NSTimers
or (since swift 2.0) NSObject's performSelector
and friends.
performSelector
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool {
NSObject.cancelPreviousPerformRequests(
withTarget: self,
selector: #selector(ViewController.getHintsFromTextField),
object: textField)
self.perform(
#selector(ViewController.getHintsFromTextField),
with: textField,
afterDelay: 0.5)
return true
}
func getHintsFromTextField(textField: UITextField) {
print("Hints for textField: \(textField)")
}
NSTimer
var timer: NSTimer? = nil
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool {
timer?.invalidate()
timer = Timer.scheduledTimer(
timeInterval: 0.5,
target: self,
selector: #selector(ViewController.getHints),
userInfo: ["textField": textField],
repeats: false)
return true
}
func getHints(timer: Timer) {
var userInfo = timer.userInfo as! [String: UITextField]
print("Hints for textField: \(userInfo["textField"])")
}
Note I am passing the textField
to delayed functions. It is not always required but it could make your life easier when textField
is not easy to access or when dealing with various text fields.
NSTimer
approach is different from performSelector
?When you call performSelector
the target is retained (in swift the target is always self
) but when you use NSTimer
the target is NOT retained. This means, if you use NSTimer
s, you have to make sure target (in this case self
) is alive by the time the timer fires. Otherwise the a crash will occur.
(BTW: performSelector
uses NSTimer
internally 😀 )
If you are interested in GCD timers this gist a good place start: maicki/TimerWithGCD.md