2017-08-05 87 views
1

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

+0

我的回答对你有帮助吗? –

+0

@ReinierMelian它的工作原理,但我最终做了一些不同的事情,因为我不想创建一个新的TextView。 – BlueBoy

+0

好@BlueBoy好运!谢谢你让我知道 –

回答

0

textFieldDidEndEditing(_ :),回复之前结束,加入这行代码:

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

DispatchQueue.main.asyncAfter(deadline: .now() + 1) { 
    doSomething() 
} 
如果你想要做一些事情的UserInterface

(UI )(显示新视图,移动框架,开始动画)

+0

但如果用户键入“嗨” - 不会有两个'doSomething()'运行,只延迟一秒? – BlueBoy

+0

对不起。我错了。委托方法是textFieldDidEndEditing(_ :) – ndPPPhz

+0

但只在文本字段退出第一个响应者之后才运行否? – BlueBoy

3

试着用这个自定义UITextField,你需要设置一个计时器1秒用户每次把一个角色在你的UITextField,并再次失效重新安排前计时器,我加入了行动,关闭允许任何的动作,充分的自由在你执行

增加检查属性对于延迟定制

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但你可以做任何哟u需要

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

这个工作!测试

希望这有助于

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()”,然后抛弃该闭包。

因此,随着用户的类型,关闭被扔掉,不再重要。最终用户将暂停或停止输入,此时您要运行的代码实际上会执行(在这种情况下,将根据文本执行搜索)。这为您提供了一种感觉反应灵敏的搜索表单,但不会浪费时间为用户输入的每个字符添加搜索(这会增加开销并开始影响用户界面性能)。

+0

你的代码令人困惑... – BlueBoy

+0

@BlueBoy:增加了更多关于发生了什么的解释。我喜欢这种方法比基于定时器的方法多一点,因为我不想使用定时器和自定义类来处理响应。 –