我正在尝试创建一个函数,我可以调用该函数来更新我的 UILabel 的 scoreLabel.text
。但是,每当我尝试更改它时,我都会收到错误消息。令我困惑的是,在 viewDidLoad()
中更改它时我没有收到错误。其他任何地方都返回以下错误:
在控制台中我也得到错误:
fatal error: unexpectedly found nil while unwrapping an Optional value.
所以我一直相信,当调用我的函数来更新文本时, View 尚未加载 UILabel。但我确定只有在 View 加载后才会调用此函数。
我已经检查/尝试过的事情:
- 我的 IBOutlet 已正确连接
- 正在调用我的函数
- 同时使用
scoreLabel.text
和self.scoreLabel.text
- 使用强弱 socket 连接
我也确信 changeTextLabel
在 scoreLabel
加载到内存后被调用。但我的错误似乎又说了一遍。
这是我的代码的完整标记。为了便于阅读,我删除了一些不相关的细节:
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/