应用程序在计时器后崩溃而不是重新启用按钮
App crashes after the timer Instead of re-enabling button
我是 XCode 的新手,我们将不胜感激。
按下按钮时,按钮应该被禁用并且应该显示一个随机数并触发一个计时器。一旦计时器完成,按钮将再次启用。
这是按钮代码:
@IBAction func MarketButton(_ sender: UIButton) {
let t = Int(arc4random_uniform(10))
MarketLabel.text = String (t)
let timer = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(MarketViewController.MarketButton), userInfo: nil, repeats: false)
sender.isEnabled = !(timer.isValid )
你这里有几个问题:
导致崩溃的原因是 MarketButton
要求您将 UIButton 作为参数传递,而计时器在触发时不会执行此操作。您可以通过 scheduledTimer
的 userInfo 参数传入按钮来完成此操作。这是关于如何做 that.
的堆栈溢出 post
但是,即使在您执行此操作之后,仍然无法正常工作。
您需要制作一个方法来处理计时器完成的时间。
类似于:
func enableButton() {
yourButton.isEnabled = true
}
然后将其作为选择器而不是 MarketButton
方法。
像这样:
let timer = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(enableButton), userInfo: nil, repeats: false)
通过将 "MarketButton" 作为计时器的选择器,您将导致无限循环。计时器完成后,它会调用该方法,然后触发另一个计时器,依此类推。
另一个问题是这两行代码:
let timer = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(MarketViewController.MarketButton), userInfo: nil, repeats: false)
sender.isEnabled = !(timer.isValid )
在这种情况下,计时器几乎总是有效的,因为您只是设置了它。所以 !(timer.isValid)
基本上总是 return false。但是,如果您听从我的建议并触发不同的方法而不是 MarketButton
,那么这将不是问题。
还有一个旁注,在命名函数时你不应该将它们大写所以 MarketButton
应该是 marketButton
.
我建议尝试根据我提供给您的信息找到解决方案。如果您有任何问题,请告诉我,欢迎来到 stack overflow!
欢迎来到 Stack Overflow。让我向您介绍一下您的代码在按下按钮后的那一刻正在做什么。
- 创建一个介于 0 和 10 之间的随机数
- 将数字放入标签
- 安排计时器启动相同的功能
- 如果计时器有效,它将禁用按钮。如果计时器无效,它将启用按钮。
然而,在计时器触发后,它会调用相同的函数。这一次它不会有相同的参数。在第一个 运行 中,按钮将自己传递给第一个参数的函数。这次,计时器将成为第一个参数。不幸的是,这是因为选择器 API 类型不安全。因此,一旦触发计时器,就会发生以下情况:
- 函数被调用
- 生成一个随机数并写入您的标签
- 新的计时器已启动
- objective C运行时间,也就是运行你的iOS应用程序,试图找到它
isEnabled
属性不会在您的计时器上找到,它会崩溃。
因此,您的计时器调用@boidkan 建议的另一个函数至关重要。我建议这样:
class TimebombViewController {
@IBOutlet weak var timerLabel: UILabel!
@IBOutlet weak var startButton: UIButton!
var timer: Timer?
@IBAction startButtonPressed(_ sender:UIButton){
timerLabel.text = Int(arc4random_uniform(10)).description
timer = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(timerFired), userInfo: nil, repeats: false)
refreshButtonState()
}
@objc timerFired(_ timer:Timer){
timer = nil
refreshButtonState()
}
func refreshButtonState(){
startButton.isEnabled = !(timer?.isValid ?? false)
}
}
我是 XCode 的新手,我们将不胜感激。
按下按钮时,按钮应该被禁用并且应该显示一个随机数并触发一个计时器。一旦计时器完成,按钮将再次启用。
这是按钮代码:
@IBAction func MarketButton(_ sender: UIButton) {
let t = Int(arc4random_uniform(10))
MarketLabel.text = String (t)
let timer = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(MarketViewController.MarketButton), userInfo: nil, repeats: false)
sender.isEnabled = !(timer.isValid )
你这里有几个问题:
导致崩溃的原因是 MarketButton
要求您将 UIButton 作为参数传递,而计时器在触发时不会执行此操作。您可以通过 scheduledTimer
的 userInfo 参数传入按钮来完成此操作。这是关于如何做 that.
但是,即使在您执行此操作之后,仍然无法正常工作。 您需要制作一个方法来处理计时器完成的时间。
类似于:
func enableButton() {
yourButton.isEnabled = true
}
然后将其作为选择器而不是 MarketButton
方法。
像这样:
let timer = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(enableButton), userInfo: nil, repeats: false)
通过将 "MarketButton" 作为计时器的选择器,您将导致无限循环。计时器完成后,它会调用该方法,然后触发另一个计时器,依此类推。
另一个问题是这两行代码:
let timer = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(MarketViewController.MarketButton), userInfo: nil, repeats: false)
sender.isEnabled = !(timer.isValid )
在这种情况下,计时器几乎总是有效的,因为您只是设置了它。所以 !(timer.isValid)
基本上总是 return false。但是,如果您听从我的建议并触发不同的方法而不是 MarketButton
,那么这将不是问题。
还有一个旁注,在命名函数时你不应该将它们大写所以 MarketButton
应该是 marketButton
.
我建议尝试根据我提供给您的信息找到解决方案。如果您有任何问题,请告诉我,欢迎来到 stack overflow!
欢迎来到 Stack Overflow。让我向您介绍一下您的代码在按下按钮后的那一刻正在做什么。
- 创建一个介于 0 和 10 之间的随机数
- 将数字放入标签
- 安排计时器启动相同的功能
- 如果计时器有效,它将禁用按钮。如果计时器无效,它将启用按钮。
然而,在计时器触发后,它会调用相同的函数。这一次它不会有相同的参数。在第一个 运行 中,按钮将自己传递给第一个参数的函数。这次,计时器将成为第一个参数。不幸的是,这是因为选择器 API 类型不安全。因此,一旦触发计时器,就会发生以下情况:
- 函数被调用
- 生成一个随机数并写入您的标签
- 新的计时器已启动
- objective C运行时间,也就是运行你的iOS应用程序,试图找到它
isEnabled
属性不会在您的计时器上找到,它会崩溃。
因此,您的计时器调用@boidkan 建议的另一个函数至关重要。我建议这样:
class TimebombViewController {
@IBOutlet weak var timerLabel: UILabel!
@IBOutlet weak var startButton: UIButton!
var timer: Timer?
@IBAction startButtonPressed(_ sender:UIButton){
timerLabel.text = Int(arc4random_uniform(10)).description
timer = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(timerFired), userInfo: nil, repeats: false)
refreshButtonState()
}
@objc timerFired(_ timer:Timer){
timer = nil
refreshButtonState()
}
func refreshButtonState(){
startButton.isEnabled = !(timer?.isValid ?? false)
}
}