从函数更新标签文本的正确方法是什么?
What is the proper way to update my label's text from a function?
我正在尝试让我的 UI 标签文本根据循环计时器以 1 为增量自动更新。标签链接到一个变量。我不确定这是否重要,但我正在使用自动布局锚点以编程方式进行 UI。
我知道这是行不通的,因为变量存在于 ViewDidLoad() 之外。我还尝试在单独的文件中设置 UILabel 的子类,但我无法找到正确的方法。我在将变量连接到子类并正确实现 didSet 时遇到了问题。
这是我的 View Controller 中的相关代码,欢迎任何建议或替代方法。
import UIKit
class ViewController: UIViewController {
var numberOfBreaths = 0
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
let breathCounter = UILabel()
breathCounter.translatesAutoresizingMaskIntoConstraints = false
breathCounter.text = "\(numberOfBreaths)"
breathCounter.textAlignment = .center
breathCounter.center = self.view.center
// Irrelevant hidden label code redacted
let startStop = RoundButton()
startStop.translatesAutoresizingMaskIntoConstraints = false
startStop.backgroundColor = .white
startStop.setTitle("breathe", for: .normal)
startStop.setTitleColor(.darkGray , for: .normal)
startStop.layer.borderWidth = 2.5
startStop.layer.borderColor = CGColor(red: 225, green: 225, blue: 0, alpha: 1)
startStop.addTarget(self, action: #selector(self.breathCount), for: .touchUpInside)
view.addSubview(breathCounter)
view.addSubview(holdTimer)
view.addSubview(startStop)
// Anchor code redacted
}
@objc func breathCount(_ sender: RoundButton) {
print("Button Tapped")
createTimer()
}
func createTimer() {
_ = Timer.scheduledTimer(timeInterval: 3.5, target: self, selector: #selector(nextBreath), userInfo: nil, repeats: true)
}
@objc func nextBreath() {
numberOfBreaths += 1
breathCounter.text = "\(numberOfBreaths)" // Error: Cannot find 'breathCounter' in scope
print(numberOfBreaths) // Prints expected number to console
}
}
View for context
如果您在视图控制器上将 breathCounter
声明为 属性(就像您对 numberOfBreaths
所做的那样,您将可以从 viewDidLoad
和nextBreath
函数。我还会参考你的 Timer
class ViewController: UIViewController {
var numberOfBreaths = 0
let breathCounter = UILabel()
var timer : Timer?
然后在 viewDidLoad
中删除现有的 let breathCounter = UILabel()
行。
在createTimer
里面:
self.timer = Timer.scheduledTimer(timeInterval: 3.5, target: self, selector: #selector(nextBreath), userInfo: nil, repeats: true)
您的错误消息:// Error: Cannot find 'breathCounter' in scope
提供了一个很好的线索……一切都与范围有关。
您在 ViewDidLoad()
方法中声明了您的 UILabel
,这就是它所在的位置;那是它的范围。 ViewDidLoad
完成后,*poof * UILabel
从内存中消失。
您需要做的是将您的 let breathCounter = UILabel()
移到 ViewDidLoad 之外,以便它与您的 ViewController 一起创建;那么只要您的 ViewController 存在于内存中,您就可以引用它。
我正在尝试让我的 UI 标签文本根据循环计时器以 1 为增量自动更新。标签链接到一个变量。我不确定这是否重要,但我正在使用自动布局锚点以编程方式进行 UI。
我知道这是行不通的,因为变量存在于 ViewDidLoad() 之外。我还尝试在单独的文件中设置 UILabel 的子类,但我无法找到正确的方法。我在将变量连接到子类并正确实现 didSet 时遇到了问题。
这是我的 View Controller 中的相关代码,欢迎任何建议或替代方法。
import UIKit
class ViewController: UIViewController {
var numberOfBreaths = 0
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
let breathCounter = UILabel()
breathCounter.translatesAutoresizingMaskIntoConstraints = false
breathCounter.text = "\(numberOfBreaths)"
breathCounter.textAlignment = .center
breathCounter.center = self.view.center
// Irrelevant hidden label code redacted
let startStop = RoundButton()
startStop.translatesAutoresizingMaskIntoConstraints = false
startStop.backgroundColor = .white
startStop.setTitle("breathe", for: .normal)
startStop.setTitleColor(.darkGray , for: .normal)
startStop.layer.borderWidth = 2.5
startStop.layer.borderColor = CGColor(red: 225, green: 225, blue: 0, alpha: 1)
startStop.addTarget(self, action: #selector(self.breathCount), for: .touchUpInside)
view.addSubview(breathCounter)
view.addSubview(holdTimer)
view.addSubview(startStop)
// Anchor code redacted
}
@objc func breathCount(_ sender: RoundButton) {
print("Button Tapped")
createTimer()
}
func createTimer() {
_ = Timer.scheduledTimer(timeInterval: 3.5, target: self, selector: #selector(nextBreath), userInfo: nil, repeats: true)
}
@objc func nextBreath() {
numberOfBreaths += 1
breathCounter.text = "\(numberOfBreaths)" // Error: Cannot find 'breathCounter' in scope
print(numberOfBreaths) // Prints expected number to console
}
}
View for context
如果您在视图控制器上将 breathCounter
声明为 属性(就像您对 numberOfBreaths
所做的那样,您将可以从 viewDidLoad
和nextBreath
函数。我还会参考你的 Timer
class ViewController: UIViewController {
var numberOfBreaths = 0
let breathCounter = UILabel()
var timer : Timer?
然后在 viewDidLoad
中删除现有的 let breathCounter = UILabel()
行。
在createTimer
里面:
self.timer = Timer.scheduledTimer(timeInterval: 3.5, target: self, selector: #selector(nextBreath), userInfo: nil, repeats: true)
您的错误消息:// Error: Cannot find 'breathCounter' in scope
提供了一个很好的线索……一切都与范围有关。
您在 ViewDidLoad()
方法中声明了您的 UILabel
,这就是它所在的位置;那是它的范围。 ViewDidLoad
完成后,*poof * UILabel
从内存中消失。
您需要做的是将您的 let breathCounter = UILabel()
移到 ViewDidLoad 之外,以便它与您的 ViewController 一起创建;那么只要您的 ViewController 存在于内存中,您就可以引用它。