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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 00:48:03