更新UILabel文本时出现问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了更新UILabel文本时出现问题相关的知识,希望对你有一定的参考价值。
我正在制作一个小游戏而且我在更新我创建的UILabel时遇到问题,以显示当前的分数。每当我尝试更新分数标签时,整个屏幕会冻结一瞬间,前一帧中的所有对象都会保留在屏幕上,而下一帧则会在其上方绘制,而分数标签不会更新。只有在我尝试更新UILabel时才会出现此问题,否则一切运行正常,没有任何打嗝。
我读到更新UILabel需要在主线程上完成,并尝试使用Dispatch.main.async这样做,但问题仍然存在。下面我发布了导致我问题的代码。
fileprivate let scoreLabel: UILabel = {
let newLabel = UILabel()
newLabel.textAlignment = .center
newLabel.textColor = .white
newLabel.text = "0"
newLabel.translatesAutoresizingMaskIntoConstraints = false
return newLabel
}()
var score: Int = 0
fileprivate lazy var displayLink: CADisplayLink = {
let newLink = CADisplayLink(target: self, selector: #selector(update))
return newLink
}()
@objc func update() {
score += 1
//Method 1: cause screen split second screen lockup
scoreLabel.text = "(score)" //doesn't work
//Method 2: cause screen split second screen lockup
DispatchQueue.main.async {
self.scoreLabel.text = "(score)" //also doesn't work
self.scoreLabel.setNeedsDisplay()
}
}
func setupLayout() {
view.addSubview(scoreLabel)
NSLayoutConstraint.activate([
scoreLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor),
scoreLabel.centerXAnchor.contraint(equalTo: view.centerXAnchor)
])
}
override func viewDidLoad() {
super.viewDidLoad()
setupLayout()
displayLink.add(to: .main, forMode: .default)
}
这对我来说很困惑,因为这个代码在Objective-C和Swift下面的版本4下工作。任何关于我做错的想法?
这也是Swift 4.2版
更新:
所以我找到了解决方案。显然autolayout是造成问题的原因。为了解决这个问题,我找到了两种方法:
- 在DispatchQueue.main.async中,首先停用布局约束。然后更新标签并重新激活布局约束并调用layoutIfNeeded()。
- 而不是使用自动布局设置您的标签手动设置带有CGRect的label.frame和使用label.center和CGPoint的位置。之后,您应该可以毫无问题地更新您的标签。
希望这有助于其他可能遇到此问题的人。
显示链接更新用于自定义绘制您的视图,而不是更新您的子视图(它们已经自己绘制);你真的需要每秒重绘60次你的标签吗?只需更新文本,系统就会将标签标记为脏标签,并在下次重绘时更新它;你不需要强迫计时。如果你确实需要类似计数器的东西,那么它需要一个普通的计时器,而不是一个displaylink计时器。
尝试layoutIfNeeded() layoutIfNeeded提前布局
Dispatch.main.async {
self.scoreLabel.text = "(score)" //also doesn't work
self.scoreLabel.layoutIfNeeded()
}
以上是关于更新UILabel文本时出现问题的主要内容,如果未能解决你的问题,请参考以下文章
Swift 线程 1:当我尝试更改 uilabel.text 时出现 EXC_BAD_INSTRUCTION
在片段java类中使用“this”和getLastSignedInAccount时出现错误[重复]
当 FragmentActivity 在 Android 中进入后台时出现 NotSerializableException