SWIFT - 在用户停止键入文本字段后1秒运行代码

时间:2017-08-05 23:25:11

标签: ios swift

在swift中,如何在用户停止输入文本字段后1秒运行一些代码?有textFieldDidChange但是在输入新字符后会立即运行代码。

3 个答案:

答案 0 :(得分:4)

尝试使用此自定义UITextField,每次用户在UITextField中放置一个字符时,您需要设置一个计时器1秒,并在重新计划之前使计时器无效,我添加了操作作为允许任何行动的封闭,在你的实施中给予充分的自由

为延迟自定义添加了Inspectable属性

import UIKit

@IBDesignable
class AfterOneSecondTextField: UITextField {

    @IBInspectable var delayValue : Double = 1.0
    var timer:Timer?

    var actionClosure : (()->Void)?

    override func awakeFromNib() {
        super.awakeFromNib()
        self.addTarget(self, action: #selector(changedTextFieldValue), for: .editingChanged)
    }

    func changedTextFieldValue(){
        timer?.invalidate()
        //setup timer
        timer = Timer.scheduledTimer(timeInterval: delayValue, target: self, selector: #selector(self.executeAction), userInfo: nil, repeats: false)
    }

    func executeAction(){
        actionClosure?()
    }

    /*
    // Only override draw() if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func draw(_ rect: CGRect) {
        // Drawing code
    }
    */

}

使用

你只需要设置类,并在我的情况下将一个闭包传递给你想要的动作是debugPrint,但你可以做任何你需要的事情

class ViewController: UIViewController {
    @IBOutlet weak var tfText: AfterOneSecondTextField!
    override func viewDidLoad() {
        super.viewDidLoad()
        tfText.actionClosure = {
            debugPrint("Test")
        }
    }

这个有效!,经过测试

希望这有帮助

答案 1 :(得分:0)

我所做的是在延迟一段时间后使用可取消的闭包来运行代码;这种方式当用户键入闭包时会一直被取消,但是当它们停留足够长时间或完成搜索或获取的代码时,实际上是在短暂的延迟后运行。

我在这里使用了可取消的闭包代码:

Cancel a timed event in Swift?

然后进入textFieldDidChange的代码如下:

 fileprivate var delayedSearchClosure : dispatch_cancelable_closure?
open func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {

    if let searchClosure = delayedSearchClosure {
        searchClosure(true)
        delayedSearchClosure = .none
    }

    delayedSearchClosure = delayClosure(0.8) { [weak self] in
        self?.doSearch(searchText)
        self?.delayedSearchClosure = .none
    }
}

为了解释这里发生的事情 - 在用户输入的文本字段的回调中,我首先终止创建的特定时间段的现有闭包。然后在下一个代码块中,它创建一个新的delayedSearchClosure,它将从现在开始执行0.8秒并调用“doSearch()”,然后抛弃闭包。

因此,当用户输入时,关闭被抛弃,不再重要。最终用户将暂停或停止键入,此时您想要运行的代码实际执行(在这种情况下,将根据文本执行搜索)。这为您提供了一个感觉响应的搜索表单,但不会浪费时间为用户键入的每个字符启动添加的搜索(这会增加开销并开始影响UI性能)。

答案 2 :(得分:-1)

textFieldDidEndEditing(_:)的末尾,在返回之前,添加以下代码行:

DispatchQueue.global().asyncAfter(deadline: .now() + 1) { 
    doSomething()
}

DispatchQueue.main.asyncAfter(deadline: .now() + 1) { 
    doSomething()
}

如果您想使用UserInterface(UI)执行某些操作(显示新视图,移动框架,启动动画)