Detect when user stopped / paused typing in Swift

烂漫一生 提交于 2019-11-27 14:03:30

问题


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!


回答1:


UPDATE 2016/09/01:

We can use NSTimers or (since swift 2.0) NSObject's performSelector and friends.

Aproach 1 : 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)")
}

Approach 2: 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.

How 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 NSTimers, 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



来源:https://stackoverflow.com/questions/29762553/detect-when-user-stopped-paused-typing-in-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!