Swift |计时器不会在无效呼叫时停止,而是加速?
Swift | The timer wont stop on invalidate call, rather speeds up?
我在这个应用程序中使用计时器制作了一个秒表,并添加了开始停止按钮来暂停和播放。
当按下按钮时,它被发送到一个使计时器无效的函数,它应该停止。
但奇怪的是,当按下停止按钮时,计时器并没有停止而是以某种方式加速了
我没有更改时间间隔,只是声明了一次。
我曾尝试在按下开始按钮后将其禁用,甚至将其隐藏。还尝试更改时间间隔但没有任何效果。我越按开始停止按钮,它越加速,开始比提到的时间间隔快得多。
startButton.frame = CGRect(x: 0, y: UIScreen.main.bounds.height * 0.9 , width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height * 0.1)
startButton.setTitle("Start Timer", for: .normal)
self.view.addSubview(startButton)
startButton.setTitleColor(.white , for: .normal)
startButton.backgroundColor = .red
startButton.addTarget(self, action: #selector(playButton(_:)), for: .allTouchEvents)
stopButton.frame = CGRect(x: 0, y: UIScreen.main.bounds.height * 0.9 , width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height * 0.1)
stopButton.setTitle("Stop Timer", for: .normal)
stopButton.setTitleColor(.white , for: .normal)
stopButton.backgroundColor = .red
stopButton.addTarget(self, action: #selector(pauseButton(_:)), for: .allTouchEvents)
@objc func playButton(_ sender : Any)
{
timer = Timer.scheduledTimer(timeInterval: 1, target: self , selector: #selector(updateTimer), userInfo: nil, repeats: true)
startButton.isEnabled = false
stopButton.isEnabled = true
isRunning = true
self.view.addSubview(stopButton)
startButton.isHidden = true
stopButton.isHidden = false
}
@objc func pauseButton(_ sender: Any) {
self.view.addSubview(startButton)
timer.invalidate()
stopButton.isHidden = true
startButton.isHidden = false
startButton.isEnabled = true
stopButton.isEnabled = false
isRunning = false
}
@objc func updateTimer(_ sender : Any)
{
counter += 0.1
titleLabel.text = String(format: "%.1f", counter)
}
尝试通过隐藏停止按钮同时添加两个按钮,并在单击按钮时隐藏和取消隐藏按钮。当您尝试停止计时器时,您的播放按钮方法每次都是 运行
据我所知,你有两个错误。
另一个答案提到了第一个。这是一个真实的建议,你不应该总是添加一个新的 UIButton 并且应该只为每个按钮使用 hide/unhide 属性。
第二个错误在于添加目标的方式。您正在使用 .allTouchEvents,但是您可能打算使用 .touchUpInside 作为您的控制状态。
请参阅以下更正后的代码供您参考:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var titleLabel: UILabel!
var startButton: UIButton!
var stopButton: UIButton!
var timer: Timer!
var counter: Double = 0.0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
startButton = UIButton(frame: CGRect(x: 0, y: UIScreen.main.bounds.height * 0.9 , width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height * 0.1))
startButton.setTitle("Start Timer", for: .normal)
startButton.setTitleColor(.white , for: .normal)
startButton.backgroundColor = .red
startButton.addTarget(self, action: #selector(playButton(_:)), for: .touchUpInside)
self.view.addSubview(startButton)
self.startButton.isHidden = false
stopButton = UIButton(frame: CGRect(x: 0, y: UIScreen.main.bounds.height * 0.9 , width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height * 0.1))
stopButton.setTitle("Stop Timer", for: .normal)
stopButton.setTitleColor(.white , for: .normal)
stopButton.backgroundColor = .red
stopButton.addTarget(self, action: #selector(pauseButton(_:)), for: .touchUpInside)
self.view.addSubview(stopButton)
self.stopButton.isHidden = true
}
@objc func playButton(_ sender : Any) {
timer = Timer.scheduledTimer(timeInterval: 1, target: self , selector: #selector(updateTimer), userInfo: nil, repeats: true)
startButton.isEnabled = false
stopButton.isEnabled = true
startButton.isHidden = true
stopButton.isHidden = false
}
@objc func pauseButton(_ sender: Any) {
timer.invalidate()
stopButton.isHidden = true
startButton.isHidden = false
startButton.isEnabled = true
stopButton.isEnabled = false
}
@objc func updateTimer(_ sender : Any)
{
counter += 0.1
titleLabel.text = String(format: "%.1f", counter)
}
}
您已经有 2 个正确答案,但我会提出我的 2p,因为我认为您开始的前提不正确。
你最大的错误是一开始就有 2 个按钮。如果您只有一个按钮并根据需要设置样式,您就不会遇到这个问题。
class MyTest {
let magicButton = UIButton()
let timer: Timer?
override viewDidLoad() {
super.viewDidLoad()
// Setup Button
magicButton.addTarget(self, action: #selector(buttonPress(_:)), for: .allTouchEvents)
magicButton.setTitleColor(.white , for: .normal)
magicButton.frame = yourFrame
view.addSubview(magicButton)
customiseButton()
}
@objc private func buttonPress() {
if timer == nil {
timer = Timer.scheduledTimer(timeInterval: 1, target: self , selector: #selector(updateTimer), userInfo: nil, repeats: true)
} else {
timer.invalidate()
}
customiseButton()
}
private func customiseButton() {
let isStartButton = timer == nil
let buttonTitle = isStartButton ? "Start" : "Stop"
let buttonBackgroundColor: UIColor = isStartButton ? .green : .red
magicButton.setTitle(buttonTitle, for: .normal)
magicButton.backgroundColor = buttonBackgroundColor
}
}
// add updateTimer function too
这样一来,您需要维护的代码就会更少,而且隐藏/显示的内容之间不会发生冲突,因此可能出错的事情也会更少。 魔法 发生在 buttonPress 方法中,如果计时器启动,您将停止它,否则您启动一个,然后快速更新按钮 UI.
我在这个应用程序中使用计时器制作了一个秒表,并添加了开始停止按钮来暂停和播放。 当按下按钮时,它被发送到一个使计时器无效的函数,它应该停止。 但奇怪的是,当按下停止按钮时,计时器并没有停止而是以某种方式加速了 我没有更改时间间隔,只是声明了一次。
我曾尝试在按下开始按钮后将其禁用,甚至将其隐藏。还尝试更改时间间隔但没有任何效果。我越按开始停止按钮,它越加速,开始比提到的时间间隔快得多。
startButton.frame = CGRect(x: 0, y: UIScreen.main.bounds.height * 0.9 , width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height * 0.1)
startButton.setTitle("Start Timer", for: .normal)
self.view.addSubview(startButton)
startButton.setTitleColor(.white , for: .normal)
startButton.backgroundColor = .red
startButton.addTarget(self, action: #selector(playButton(_:)), for: .allTouchEvents)
stopButton.frame = CGRect(x: 0, y: UIScreen.main.bounds.height * 0.9 , width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height * 0.1)
stopButton.setTitle("Stop Timer", for: .normal)
stopButton.setTitleColor(.white , for: .normal)
stopButton.backgroundColor = .red
stopButton.addTarget(self, action: #selector(pauseButton(_:)), for: .allTouchEvents)
@objc func playButton(_ sender : Any)
{
timer = Timer.scheduledTimer(timeInterval: 1, target: self , selector: #selector(updateTimer), userInfo: nil, repeats: true)
startButton.isEnabled = false
stopButton.isEnabled = true
isRunning = true
self.view.addSubview(stopButton)
startButton.isHidden = true
stopButton.isHidden = false
}
@objc func pauseButton(_ sender: Any) {
self.view.addSubview(startButton)
timer.invalidate()
stopButton.isHidden = true
startButton.isHidden = false
startButton.isEnabled = true
stopButton.isEnabled = false
isRunning = false
}
@objc func updateTimer(_ sender : Any)
{
counter += 0.1
titleLabel.text = String(format: "%.1f", counter)
}
尝试通过隐藏停止按钮同时添加两个按钮,并在单击按钮时隐藏和取消隐藏按钮。当您尝试停止计时器时,您的播放按钮方法每次都是 运行
据我所知,你有两个错误。
另一个答案提到了第一个。这是一个真实的建议,你不应该总是添加一个新的 UIButton 并且应该只为每个按钮使用 hide/unhide 属性。
第二个错误在于添加目标的方式。您正在使用 .allTouchEvents,但是您可能打算使用 .touchUpInside 作为您的控制状态。
请参阅以下更正后的代码供您参考:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var titleLabel: UILabel!
var startButton: UIButton!
var stopButton: UIButton!
var timer: Timer!
var counter: Double = 0.0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
startButton = UIButton(frame: CGRect(x: 0, y: UIScreen.main.bounds.height * 0.9 , width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height * 0.1))
startButton.setTitle("Start Timer", for: .normal)
startButton.setTitleColor(.white , for: .normal)
startButton.backgroundColor = .red
startButton.addTarget(self, action: #selector(playButton(_:)), for: .touchUpInside)
self.view.addSubview(startButton)
self.startButton.isHidden = false
stopButton = UIButton(frame: CGRect(x: 0, y: UIScreen.main.bounds.height * 0.9 , width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height * 0.1))
stopButton.setTitle("Stop Timer", for: .normal)
stopButton.setTitleColor(.white , for: .normal)
stopButton.backgroundColor = .red
stopButton.addTarget(self, action: #selector(pauseButton(_:)), for: .touchUpInside)
self.view.addSubview(stopButton)
self.stopButton.isHidden = true
}
@objc func playButton(_ sender : Any) {
timer = Timer.scheduledTimer(timeInterval: 1, target: self , selector: #selector(updateTimer), userInfo: nil, repeats: true)
startButton.isEnabled = false
stopButton.isEnabled = true
startButton.isHidden = true
stopButton.isHidden = false
}
@objc func pauseButton(_ sender: Any) {
timer.invalidate()
stopButton.isHidden = true
startButton.isHidden = false
startButton.isEnabled = true
stopButton.isEnabled = false
}
@objc func updateTimer(_ sender : Any)
{
counter += 0.1
titleLabel.text = String(format: "%.1f", counter)
}
}
您已经有 2 个正确答案,但我会提出我的 2p,因为我认为您开始的前提不正确。
你最大的错误是一开始就有 2 个按钮。如果您只有一个按钮并根据需要设置样式,您就不会遇到这个问题。
class MyTest {
let magicButton = UIButton()
let timer: Timer?
override viewDidLoad() {
super.viewDidLoad()
// Setup Button
magicButton.addTarget(self, action: #selector(buttonPress(_:)), for: .allTouchEvents)
magicButton.setTitleColor(.white , for: .normal)
magicButton.frame = yourFrame
view.addSubview(magicButton)
customiseButton()
}
@objc private func buttonPress() {
if timer == nil {
timer = Timer.scheduledTimer(timeInterval: 1, target: self , selector: #selector(updateTimer), userInfo: nil, repeats: true)
} else {
timer.invalidate()
}
customiseButton()
}
private func customiseButton() {
let isStartButton = timer == nil
let buttonTitle = isStartButton ? "Start" : "Stop"
let buttonBackgroundColor: UIColor = isStartButton ? .green : .red
magicButton.setTitle(buttonTitle, for: .normal)
magicButton.backgroundColor = buttonBackgroundColor
}
}
// add updateTimer function too
这样一来,您需要维护的代码就会更少,而且隐藏/显示的内容之间不会发生冲突,因此可能出错的事情也会更少。 魔法 发生在 buttonPress 方法中,如果计时器启动,您将停止它,否则您启动一个,然后快速更新按钮 UI.