在swift中,如何在用户停止输入文本字段后1秒运行一些代码?有textFieldDidChange
但是在输入新字符后会立即运行代码。
答案 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)执行某些操作(显示新视图,移动框架,启动动画)