更新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是造成问题的原因。为了解决这个问题,我找到了两种方法:

  1. 在DispatchQueue.main.async中,首先停用布局约束。然后更新标签并重新激活布局约束并调用layoutIfNeeded()。
  2. 而不是使用自动布局设置您的标签手动设置带有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

更新文本框 ASP.NET 时出现问题

在片段java类中使用“this”和getLastSignedInAccount时出现错误[重复]

UILabel 文本未更新

在 Google Docs 中批量更新时出现内部错误

当 FragmentActivity 在 Android 中进入后台时出现 NotSerializableException