SKLabelNode结合NSMutableAttributedString无阴影问题咨询
SKLabelNode + NSMutableAttributedString 阴影不显示的解决办法
嘿,我之前也踩过这个坑!SpriteKit的SKLabelNode对NSAttributedString的属性支持有局限性,你代码里用的NSShadowAttributeName是UIKit控件(比如UILabel)才认的属性,放到SKLabelNode里会直接被忽略,这就是阴影不出来的原因。下面给你两个实用的解决方案,看你需求选:
方案一:用SKLabelNode自带的阴影属性(推荐,简单高效)
如果你的整个标签文本阴影样式是统一的,完全没必要用富文本的阴影属性,直接用SKLabelNode原生的阴影设置就行,适配性更好:
let label = SKLabelNode() label.text = "MY LABEL" label.font = UIFont.systemFont(ofSize: 24) // 补全你之前没写完的字体设置 label.fontColor = .white label.strokeColor = .black label.strokeWidth = -3 // 直接设置SKLabelNode的阴影 label.shadowColor = .gray label.shadowOffset = CGSize(width: 2, height: -2) label.shadowBlurRadius = 5 // 对齐方式用label的alignmentMode替代段落样式 label.alignmentMode = .right // 别忘了设置位置和添加到场景 label.position = CGPoint(x: self.size.width/2, y: self.size.height/2) addChild(label)
这个方法不仅代码更简洁,而且SpriteKit对原生属性的渲染性能也比富文本好。
方案二:用CoreText渲染成图片(适合复杂富文本场景)
如果你必须用NSMutableAttributedString(比如不同文本段有不同的阴影、颜色等样式),那可以把富文本渲染成UIImage,再转换成SKSpriteNode来显示:
// 先补全你的字体设置 let customFont = UIFont.systemFont(ofSize: 24) let paragraph = NSMutableParagraphStyle() paragraph.alignment = .right paragraph.tailIndent = -3 let shadow = NSShadow() shadow.shadowBlurRadius = 5 shadow.shadowColor = UIColor.gray shadow.shadowOffset = CGSize(width: 2, height: -2) // 构建完整的富文本 let attributedText = NSMutableAttributedString(string: "MY LABEL", attributes: [ NSAttributedString.Key.font: customFont, NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.strokeColor: UIColor.black, NSAttributedString.Key.strokeWidth: -3, NSAttributedString.Key.paragraphStyle: paragraph, NSAttributedString.Key.shadow: shadow ]) // 写个工具方法把富文本转成UIImage func attrStringToImage(_ attrString: NSAttributedString) -> UIImage? { let textSize = attrString.boundingRect( with: CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude), options: [.usesLineFragmentOrigin, .usesFontLeading], context: nil ).size UIGraphicsBeginImageContextWithOptions(textSize, false, UIScreen.main.scale) attrString.draw(in: CGRect(origin: .zero, size: textSize)) let resultImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return resultImage } // 转换成SKSpriteNode并添加到场景 if let labelImage = attrStringToImage(attributedText) { let labelSprite = SKSpriteNode(texture: SKTexture(image: labelImage)) labelSprite.position = CGPoint(x: self.size.width/2, y: self.size.height/2) addChild(labelSprite) }
这个方法虽然麻烦一点,但能实现复杂的富文本样式需求,包括不同段落的阴影差异。
内容的提问来源于stack exchange,提问作者Anton Shevtsov
相关产品推荐
相关产品推荐

