从另一个不相关的 class 改变 ViewController 中的 UILabel

Mutating UILabels in the ViewController from another unrelated class

我一直在为我的 tvOS sprite 工具包游戏制作分数和高分显示。我有两个 classes。其中一个 class 被称为 "GameViewController," UIViewController,另一个是我的播放器的 SKSpriteNode 的子class。我想要做的是每五次更新,分数就会更新。分数和高分的标签是通过我的 GameViewController class 中的变量访问的。在我的播放器 class 中完成更新,所以我需要在我的 GameViewController class from 我的播放器 class 中触发一个方法。

我已经尝试了一些东西。我得到的最远的是使用此方法使用 "Protocols" 和 "Delegates." 我有一个 protocol class 调用 "ScoreUpdateResponder" 方法:

scoreUpdate(let score: Int)

因此,我的 GameViewController 实现了(?我是一名 Java 开发人员,试图将这里的点连接起来)响应者 class。所以我的缩减 class 结构如下所示:

玩家Class:

class Player: SKSpriteNode
{
    weak var responder: ScoreUpdateResponder?

    init(responder : ScoreUpdateResponder) 
    {
        self.responder = responder
    }

    let score = 0

    func update()
    {
      if(score % 5 == 0)
      {
        responder?.updateScore(score / 5)
      }

      score++;
    }
}

** ScoreUpdateResponder class**

protocol ScoreUpdateResponder : class
{
    func updateScore(let score: Int)

}

然后我的 GameViewController 是:

class GameViewController: UIViewController, ScoreUpdateResponder
{
  func updateScore(score: Int)
  {
    scoreValue.text = String(score)

    if(score > Int.init(highscoreValue.text!)!)
    {
      highscoreValue.text = String(score)
    }
  }
}

我知道我一定漏掉了什么。我怀疑它与我对响应程序的初始化有关,或者更普遍地在播放器 class 中。有帮助吗?

我将在这里做一些假设。

假设

  • 这个游戏只有一个玩家,用单例表示
  • 未显示的内容负责调用 player.Update()

我认为您可能 运行 遇到的问题是 let score = 0 行。我认为您实际上想要做的是:var score = 0let 有效地定义了一个常量。

我还编辑了一些代码,使其更符合常见的 swift 风格指南。

class GameViewController: UIViewController {

    @IBOutlet private weak var scoreValue: UILabel!
    @IBOutlet private weak var highscoreValue: UILabel!

    var player = Player()

    override func viewDidLoad() {
        super.viewDidLoad()
        player.delegate = self
    }

    ...

}

// MARK: PlayerDelegate
extension GameViewController: PlayerDelegate {

    func playerDidUpdateScore(score: Int) {
        self.scoreValue.text = String(score)

        guard let highScoreText = highscoreValue.text, highScore = Int(highScoreText) where score > highScore else {
                return
        }

        self.highscoreValue.text = String(score)
    }
}

protocol PlayerDelegate {
    func playerDidUpdateScore(score: Int)
}

class Player: SKSpriteNode {

    var delegate: PlayerDelegate?
    static var score = 0

    func update() {
        if self.score % 5 == 0 {
            self.delegate?.playerDidUpdateScore(self.score / 5)
        }

        self.score++;
    }
}