ios - 更新 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)
}
这让我感到困惑,因为这段代码在版本 4 以下的 Objective-C 和 Swift 中工作。关于我做错了什么有什么想法吗?
这也在 Swift 4.2 版上
更新:
所以我找到了解决方案。显然自动布局是导致问题的原因。为了解决这个问题,我找到了两种方法:
在 DispatchQueue.main.async 中,首先停用您的布局约束。然后更新您的标签并重新激活您的布局约束并调用 layoutIfNeeded()。
而不是使用自动布局设置您的标签,而是使用 CGRect 手动设置 label.frame,使用 label.center 和 CGPoint 设置位置。之后,您应该可以毫无问题地更新您的标签。
希望这可以帮助其他可能遇到此问题的人。
解决方案
尝试 layoutIfNeeded()
layoutIfNeeded 尽早强制布局
Dispatch.main.async {
self.scoreLabel.text = "\(score)" //also doesn't work
self.scoreLabel.layoutIfNeeded()
}
推荐阅读
- c# - EF Core SQLite 检查表是否存在
- flutter - 为什么我的颤振代码运行两次而不是运行一次?
- python - 为什么 django 不为我的模型进行迁移
- variables - terraform 看不到对象变量
- python - 将一个数组添加到另一个数组中,但间隔相等
- reactjs - 坚持在 React 中创建动态表单构建器
- ios - 为什么 iPad Pro 11 英寸(第二代)的 UIView.contentScaleFactor 为 1 而 UIScreen.main.scale 为 2?
- html - Flexbox 忽略 justify-content、align-content 等以消除子元素之间的间隙
- dataflow-diagram - 数据流图(DFD)建模疑惑
- javascript - 在 React 组件中将 Css 类加载为字符串