SKLabelNode多行文本如何居中对齐?horizontalAlignmentMode不相关
解决SKLabelNode多行文本居中对齐的问题
你完全说对了——SKLabelNode的horizontalAlignmentMode确实只控制整个文本块相对于节点锚点的位置,根本不管多行文本里每行的对齐方式,默认的多行就是左对齐,这确实挺坑的。不过有两个靠谱的解决方案:
方法一:使用富文本(NSAttributedString)设置段落样式
这是最直接的方法,通过给SKLabelNode设置带段落样式的富文本,让每行文本居中对齐:
// 创建段落样式 let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.alignment = .center paragraphStyle.lineBreakMode = .byWordWrapping // 保持自动换行的逻辑 // 设置富文本属性 let attributes: [NSAttributedString.Key: Any] = [ .font: UIFont(name: "Arial", size: 24)!, // 替换成你需要的字体 .foregroundColor: UIColor.white, .paragraphStyle: paragraphStyle ] // 创建富文本并赋值给SKLabelNode let centeredLabel = SKLabelNode() centeredLabel.attributedText = NSAttributedString(string: "abcde\nfg", attributes: attributes) centeredLabel.numberOfLines = 0 // 允许自动换行
这样设置后,多行文本的每一行都会居中对齐,同时horizontalAlignmentMode还能继续控制整个文本块在节点中的位置(比如设为.center的话,整个居中的文本块会以节点的锚点为中心)。
方法二:手动拼接多个SKLabelNode(适合复杂排版需求)
如果你的多行文本需要更精细的控制(比如每行字体大小/颜色不同),可以把每行文本做成单独的SKLabelNode,然后手动排列成居中的效果:
// 拆分文本为单行数组 let textLines = ["abcde", "fg"] let lineSpacing: CGFloat = 8 // 行间距 let font = UIFont(name: "Arial", size: 24)! // 创建容器节点来承载所有行 let multiLineLabel = SKNode() var currentY: CGFloat = 0 // 遍历每行创建label并排列 for line in textLines.reversed() { // 倒序遍历,方便从下往上排列 let lineLabel = SKLabelNode(text: line) lineLabel.font = font lineLabel.fontColor = .white lineLabel.horizontalAlignmentMode = .center // 单行本身居中 lineLabel.position = CGPoint(x: 0, y: currentY) multiLineLabel.addChild(lineLabel) currentY += lineLabel.frame.height + lineSpacing } // 调整容器节点的锚点,让整个多行文本的中心在容器的原点 multiLineLabel.position = CGPoint(x: 0, y: -currentY/2 + lineSpacing/2)
这种方法虽然麻烦,但灵活性很高,适合有特殊排版需求的场景。
内容的提问来源于stack exchange,提问作者Fattie




