在Swift中检测用户停止/暂停输入

14

我在stackoverflow上搜索到了解决方案,将其转换为Swift语言后似乎无效,选择器仍然被执行。

 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)
}

有没有更好的方法在Swift中实现这个?谢谢!

1个回答

56

更新于2016/09/01:

我们可以使用NSTimers,或者(自Swift 2.0以来)NSObject的performSelector和相关方法。

方法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)")
}

方法二: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"])")
}

请注意,我将textField传递给延迟函数。这并不总是必需的,但当textField难以访问或处理各种文本字段时,它可以使您的生活更轻松。

NSTimer方法与performSelector方法有何不同?

当您调用performSelector方法时,目标保留(在Swift中,目标始终为self),但当您使用NSTimer时,目标不会被保留。这意味着,如果您使用NSTimer,您必须确保目标(在本例中为self)在计时器触发时仍然存在。否则将导致崩溃。

(顺便说一句:performSelector内部使用NSTimer

如果您对GCD计时器感兴趣,这个代码片段是一个很好的起点:

maicki/TimerWithGCD.md


好的解决方案。谢谢! - Thomás Pereira
这是一个非常棒的答案,因为 var userInfo = timer.userInfo as! [String: UITextField] 可以获取文本框中的文本和文本框本身的信息!正是我所需要的 :) - Lance Samaria

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接