You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义SKButton(SKNode子类)不显示问题求助 | Swift SpriteKit

SpriteKit自定义SKButton不显示问题排查

问题描述

我编写了一个继承自SKNode的SKButton类,问题是尽管已将其添加到SpriteKit场景中,按钮仍未显示;但我同时编写的摇杆却能正常展示。请问我哪里出错了?

SKButton代码如下:

import SpriteKit
class SKButton: SKNode {
    let background: SKSpriteNode = SKSpriteNode(color: UIColor.red, size: CGSize(width: 100, height: 10))
    let text: SKLabelNode = SKLabelNode()
    var buttonText: String = ""
    var backgroundColor: UIColor = UIColor.red
    var fontSize: CGFloat = 0.0
    var fontName: String = ""
    var fontColor: UIColor = UIColor.white
    var buttonAction: (() -> ())?
    
    init(text: String, backgroundColor: UIColor, fontName: String, fontSize: CGFloat, fontColor: UIColor) {
        super.init()
        buttonText = text
        self.backgroundColor = backgroundColor
        self.fontName = fontName
        self.fontSize = fontSize
        self.fontColor = fontColor
        initialize()
        addChild(background)
        addChild(self.text)
        print("init")
    }
    
    func tapped(touch: UITouch) {
        let node: SKNode = atPoint(touch.location(in: self))
        if let name = node.name {
            if name == "B" || name == "T" {
                if let buttonAction = buttonAction {
                    buttonAction()
                    print("tapped")
                }
            }
        }
    }
    
    func initialize() {
        text.verticalAlignmentMode = SKLabelVerticalAlignmentMode.center
        text.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.center
        text.fontSize = fontSize
        text.fontColor = fontColor
        text.fontName = fontName
        text.text? = buttonText
        text.position = CGPoint.zero
        text.zPosition = 1
        text.name = "T"
        background.zPosition = 0
        background.position = CGPoint.zero
        background.size = CGSize(width: text.frame.width * 1.25, height: text.frame.height * 1.5)
        background.color = backgroundColor
        background.name = "B"
        print("initialize")
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

我在场景中创建按钮的代码:

let startButton: SKButton = SKButton(text: "START", backgroundColor: UIColor.red, fontName: "Arial", fontSize: 20, fontColor: UIColor.white)
startButton.position = CGPoint(x: size.width / 2, y: size.height / 2 + startButton.background.size.height * 0.75)
addChild(startButton)

我已查阅YouTube和StackOverflow但未找到解决方案,可能有所遗漏,但确实已尽力查找,因此在此求助。


问题分析与修复

我帮你找到核心问题啦!问题出在initialize()方法里的这行代码:

text.text? = buttonText

SKLabelNode的text属性是可选类型String?,当你用text?进行赋值时,只有当前text不为nil的情况下,赋值操作才会生效。但刚初始化的SKLabelNode默认text是nil,这就导致你的标签完全没有文本内容!

没有文本的SKLabelNode的frame尺寸是(0,0),接下来你用text.frame.width和text.frame.height计算背景的大小,结果背景也变成了CGSize(width: 0, height: 0)——整个按钮节点没有任何可见元素,自然就看不见了。

修复步骤:

把这行错误的代码改成直接赋值:

text.text = buttonText

另外还有一个小的逻辑优化点:你当前是先调用initialize()配置子节点属性,再把background和text添加到父节点。虽然这不会影响显示,但逻辑上更合理的顺序是先添加子节点,再配置它们的属性,调整后的init方法可以改成这样:

init(text: String, backgroundColor: UIColor, fontName: String, fontSize: CGFloat, fontColor: UIColor) {
    super.init()
    buttonText = text
    self.backgroundColor = backgroundColor
    self.fontName = fontName
    self.fontSize = fontSize
    self.fontColor = fontColor
    // 先添加子节点
    addChild(background)
    addChild(self.text)
    // 再配置属性
    initialize()
    print("init")
}

做完这些修改后,你的按钮应该就能正常显示了。如果还有疑问,可以打印一下startButton.background.size和startButton.text.frame的数值,确认尺寸是否符合预期~

内容的提问来源于stack exchange,提问作者chicken

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 18:52:59