ios - 更改 UILabel 文本仅适用于 viewDidLoad()

标签 ios swift sprite-kit uikit uilabel

我正在尝试创建一个函数,我可以调用该函数来更新我的 UILabel 的 scoreLabel.text。但是,每当我尝试更改它时,我都会收到错误消息。令我困惑的是,在 viewDidLoad() 中更改它时我没有收到错误。其他任何地方都返回以下错误:

Imgur Link

在控制台中我也得到错误:

fatal error: unexpectedly found nil while unwrapping an Optional value.

所以我一直相信,当调用我的函数来更新文本时, View 尚未加载 UILabel。但我确定只有在 View 加载后才会调用此函数。

我已经检查/尝试过的事情:

  • 我的 IBOutlet 已正确连接
  • 正在调用我的函数
  • 同时使用 scoreLabel.textself.scoreLabel.text
  • 使用强弱 socket 连接

我也确信 changeTextLabelscoreLabel 加载到内存后被调用。但我的错误似乎又说了一遍。

这是我的代码的完整标记。为了便于阅读,我删除了一些不相关的细节:

import UIKit
import SpriteKit

class GameViewController: UIViewController {



@IBOutlet weak var scoreLabel: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()
    //This is where all my other code was
    print(scoreLabel.text)
    scoreLabel.text = "Testing" //This line can be run
}

func changeTextLabel() {
    print("changeTextLabel called")
    if self.scoreLabel != nil {
        self.scoreLabel.text = "yay"
    } else {
        print("scoreLabel is nil") //This is called every time
    }
}
}

谢谢你的时间

编辑:GameScene.swift

这只是应该关注的部分

func projectileDidCollideWithMonster(projectile: SKSpriteNode, monster: SKSpriteNode) {
    print("Hit")
    let storyBoard = UIStoryboard(name: "Main", bundle: nil)
    let object = storyBoard.instantiateViewController(withIdentifier: "GameViewController") as! GameViewController

    object.changeTextLabel()
    projectile.removeFromParent()
    monster.removeFromParent()
}

最佳答案

我不完全了解你的项目设置,但你的方法看起来很复杂,这不是你在 SpriteKit 游戏中应该做的。所以我认为告诉您如何解决当前的问题不是一个好主意。

您应该直接在相关的 SKScene 中使用 SpriteKit API(SKLabelNodes、SKSpriteNodes、SKNodes 等)创建您的 UI,例如标签、按钮等。

您的 GameViewController 应该只真正处理呈现 SKScenes。所以除了加载第一个 SKScene 之外应该没有其他代码。

如果您有多个 SKScenes(MenuScene、ShopScene、SettingScene 等),您的方法将失败,因为得分标签将显示在所有 SKScenes 中。 GameViewController 呈现您所有的 SKScenes,因此添加到 GameViewController 的内容会在所有 SKScenes 中显示。这意味着您必须为每个场景删除/添加标签和其他 UI,这会很困惑。

因此,要创建乐谱标签,您应该直接在相关场景中执行此操作。我喜欢使用 lazy var 方法将标签的设置代码保存在同一位置。

class GameScene: SKScene {

      lazy var scoreLabel: SKLabelNode = {
          let label = SKLabelNode(fontNamed: "HelveticaNeue")
          label.text = "SomeText"
          label.fontSize = 22
          label.fontColor = .yellow
          label.position = CGPoint(x: self.frame.midX, y: self.frame.midY)
          return label
      }()

      override func didMove(to view: SKView) {

          addChild(scoreLabel)
      }
} 

然后您可以直接在您拥有的碰撞代码中像这样更新它。

scoreLabel.text = "NewText"

现在,当您从 1 个 SKScene 更改为另一个 SKScene 时,您不必担心删除此标签,SpriteKit 会为您完成。

您也可以使用 xCodes 关卡编辑器以可视方式添加此标签,类似于 Storyboard。这引出了我的最终建议,即 Storyboard并没有真正用于 SpriteKit 游戏。 Storyboard适用于 ViewController,而在 SpriteKit 中,您使用的是 SKScenes。

希望对你有帮助

关于ios - 更改 UILabel 文本仅适用于 viewDidLoad(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40479672/

相关文章:

ios - Controller 中泛型类的属性注入(inject)

ios - SKAction.rotate 未在 SKCameraNode 上运行

ios7 - SpriteKit 中的缩放和滚动

swift - 在 Swift 中终止应用程序时调用函数

ios - iOS 7 突出显示时为 UIButton 设置标题颜色

ios - 检测所有应用程序的手势

ios - 在日期之间执行操作数

ios - UISegmentedControl 的动画栏按钮没有移动?

ios - 关于iphone分发私钥问题

ios - UIDocumentInteractionController 不打开 pdf 文件