使用NSAttributedString设置文字描边时,字符2、6显示异常求助
字符描边显示异常的原因与解决方法
问题原因
当strokeWidth设为负数时,CoreText会先绘制白色描边,再用前景色填充字符内部。但系统黑粗体中“2”“6”这类带闭合区域的字符,填充操作会覆盖闭合区域内的描边,导致这些字符的内部描边消失,显示异常。
解决方法
方法1:使用双层UILabel叠加
创建两个UILabel,分别处理描边和填充,将填充Label放在描边Label上方:
override func viewDidLoad() { super.viewDidLoad() // 描边Label(底层) let strokeLabel = UILabel() strokeLabel.frame = CGRect(x: 20, y: 100, width: 400, height: 100) strokeLabel.font = UIFont.systemFont(ofSize: 88, weight: .black) let strokeAttrs: [NSAttributedString.Key: Any] = [ .strokeWidth: 2, .strokeColor: UIColor.white ] strokeLabel.attributedText = NSAttributedString(string: "123456", attributes: strokeAttrs) view.addSubview(strokeLabel) // 填充Label(上层) let fillLabel = UILabel() fillLabel.frame = strokeLabel.frame fillLabel.font = strokeLabel.font fillLabel.textColor = .orange fillLabel.text = "123456" view.addSubview(fillLabel) }
方法2:自定义UILabel重写绘制逻辑
通过重写drawText(in:)方法,先绘制描边再绘制填充,确保描边不被覆盖:
class StrokeLabel: UILabel { /// 描边颜色 var strokeColor: UIColor = .white /// 描边宽度 var strokeWidth: CGFloat = 2 override func drawText(in rect: CGRect) { guard let text = text, let font = font else { super.drawText(in: rect) return } // 配置描边属性 let strokeAttributes: [NSAttributedString.Key: Any] = [ .strokeColor: strokeColor, .strokeWidth: strokeWidth, .font: font ] // 先绘制描边 text.draw(in: rect, withAttributes: strokeAttributes) // 再绘制填充 super.drawText(in: rect) } }
使用自定义Label的代码:
override func viewDidLoad() { super.viewDidLoad() let testLabel = StrokeLabel() testLabel.frame = CGRect(x: 20, y: 100, width: 400, height: 100) testLabel.font = UIFont.systemFont(ofSize: 88, weight: .black) testLabel.textColor = .orange testLabel.strokeColor = .white testLabel.strokeWidth = 2 testLabel.text = "123456" view.addSubview(testLabel) }
内容的提问来源于stack exchange,提问作者ImWH
相关产品推荐
相关产品推荐

