UIKit中NSString绘制方法忽略NSMutableParagraphStyle属性问题
问题原因
你当前使用的 NSAttributedString.draw(at:) 方法仅支持在指定坐标点按照文本自身尺寸左对齐绘制,系统无法获取段落对齐所依赖的容器边界信息,因此 NSParagraphStyle 中所有和段落布局相关的属性(包括对齐方式、行间距、缩进、换行规则等)都会被忽略。段落样式的配置必须依赖一个明确的绘制矩形区域才能生效,仅传入绘制起始点无法提供布局所需的参考范围。
解决方案
根据你的需求可以选择以下两种修改方案:
方案1:轻量适配对齐需求(无需依赖段落样式)
如果你只需要实现对齐效果,不需要用到段落样式的其他属性,可以直接在绘制前根据对齐方式调整文本绘制的起始坐标:
func text(_ string: String, _ x: CGFloat, _ y: CGFloat) { let attributedString = NSAttributedString(string: string, attributes: attributes) // 计算文本自身的尺寸 let textSize = attributedString.size() var drawOrigin = CGPoint(x: x, y: y) // 根据对齐方式偏移绘制起始点 switch settings.textAlign { case .right: drawOrigin.x -= textSize.width case .center: drawOrigin.x -= textSize.width / 2 case .left: break @unknown default: break } attributedString.draw(at: drawOrigin) }
方案2:完整支持所有段落样式属性
如果你需要 NSParagraphStyle 中配置的行间距、缩进、换行规则等所有属性都生效,可以改用 draw(in:) 方法传入明确的绘制矩形区域:
func text(_ string: String, _ anchorX: CGFloat, _ y: CGFloat, maxDrawWidth: CGFloat = UIScreen.main.bounds.width) { let attributedString = NSAttributedString(string: string, attributes: attributes) // 计算文本实际需要的高度 let textHeight = attributedString.boundingRect( with: CGSize(width: maxDrawWidth, height: CGFloat.greatestFiniteMagnitude), options: .usesLineFragmentOrigin, context: nil ).height var drawRect = CGRect.zero drawRect.size.height = textHeight // 根据对齐方式设置绘制矩形 switch settings.textAlign { case .left: drawRect.origin = CGPoint(x: anchorX, y: y) drawRect.size.width = maxDrawWidth - anchorX case .right: drawRect.origin = CGPoint(x: 0, y: y) drawRect.size.width = anchorX case .center: drawRect.origin = CGPoint(x: anchorX - maxDrawWidth/2, y: y) drawRect.size.width = maxDrawWidth @unknown default: drawRect.origin = CGPoint(x: anchorX, y: y) drawRect.size.width = maxDrawWidth } attributedString.draw(in: drawRect) }
两种方案都可以实现你测试代码中预期的右对齐、居中对齐、左对齐效果,方案2还可以保证你配置的行间距等其他段落属性正常生效。
内容的提问来源于stack exchange,提问作者rikitikitavi
相关产品推荐
相关产品推荐

