微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

UITextField +计时器问题-检查“编辑更改”但仅一次启动计时器?

如何解决UITextField +计时器问题-检查“编辑更改”但仅一次启动计时器?

全面披露: 对于所有与swift / UIKit相关的事情,我都是新手,所以希望您能原谅我的无知。


因此,我要执行的基本操作是,在将任何字符输入到UITextField的那一刻,计时器立即开始倒计时 (不只是因为专注而触发)

除了交互作用,每次输入文本字段中的字符时,计时器都会递归地启动timeInterval

键入7个以上的字符后,我的60秒计时器在不到几秒钟的时间内远远超过了0。

使用editingDidBegin解决”了该问题,但是在此参数中,当文本字段被点击并集中显示时,计时器启动,这对于我要执行的操作来说并不理想。

我的ViewController代码

import UIKit

class SecondViewController: UIViewController,UITextFieldDelegate {
    var textField: UITextField?
    @IBOutlet weak var countDownLabel: UILabel!   
    var seconds = 60
    var timer = Timer()
    @IBAction func inputTextBar(_ sender: Any) {
        func inputTextBar() {
            self.becomeFirstResponder()
        }
        timer = Timer.scheduledTimer(timeInterval: 1,target: self,selector: #selector(SecondViewController.counterb),userInfo: nil,repeats: true)
    }
    @objc func counterb() {
        seconds -= 1
        countDownLabel.text = String(seconds)
        if seconds == 0 {
            timer.invalidate()
            countDownLabel.text = "Time's Up!"
        }
    }
    var count = 10
    override func viewDidLoad() {
        super.viewDidLoad()
        textField?.delegate = self
        textField?.becomeFirstResponder()
    }
}

其他值得注意的困惑::如果只键入一个字符,计时器将正常运行并在0秒时打印“ Times Up!” 。然后停止。

但是,如果它在我提到的速度堆积上,则在键入几个字符后,计时器会飞过0,并且永远不会失效。

我认为这是一个刷新问题。

编辑:

好的,我发现使计时器变量weak可以使计时器保持不堆积的状态。但是,使用弱变量,键入UITextField时计时器根本不会运行!

半固定代码

weak var timer: Timer?
@IBAction func inputTextBar(_ sender: AnyObject) {
    timer?.invalidate()      
    timer = Timer.scheduledTimer(timeInterval: 1.0,selector: #selector(SecondViewController.loop),repeats: true)
}    
@objc func loop() {
    seconds -= 1
    countDownLabel.text = String(seconds)   
    if self.seconds == 0 {
        timer?.invalidate()
        countDownLabel.text = "Time's Up!"
    }   
}

解决方法

首先将您的计时器声明更改为可选。然后,您可以简单地检查它是否为nil,如果为true则安排您的计时器。其次,您永远不要依靠计时器来测量经过时间。只需创建一个结束日期,然后添加所需的时间间隔即可。这样,您可以在使计时器无效时简单地检查now是否大于或等于endDate。仅使用计时器来更新UI,并且您可以简单地检查从现在开始更新标签时的时间间隔。下面的代码是在浏览器中编写的,因此可能会有一些错误,但是您可以了解如何实现目标。

class SecondViewController: UIViewController {
    @IBOutlet weak var textField: UITextField!
    @IBOutlet weak var countDownLabel: UILabel!
    var endDate: Date? = nil
    var timer: Timer? = nil
    override func viewDidLoad() {
        super.viewDidLoad()
        textField.addTarget(self,action: #selector(editingChanged),for: .editingChanged)
        textField.becomeFirstResponder()
    }
    @objc func editingChanged(_ textField: UITextField) {
        if timer == nil {
            timer = .scheduledTimer(timeInterval: 1,target: self,selector: #selector(counterb),userInfo: nil,repeats: true)
            endDate = Date().addingTimeInterval(60)
        }
    }
    @objc func counterb() {
        countDownLabel.text = String(format: "%.0f",endDate!.timeIntervalSinceNow.rounded(.up))
        if Date() >= endDate! {
            timer?.invalidate()
            timer = nil
            endDate = nil
            countDownLabel.text = "Time's Up!"
        }
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。