NSMutableParagraphStyle 被 UIKit 的 NSString 绘制方法忽略

NSMutableParagraphStyle is ignored with UIKit's NSString draw method

我正在尝试为 iOS/iPadOS 框架创建一个简单的 text() 函数,该函数仅在屏幕上的坐标处显示文本。它支持全局 textAlignment 状态,可以设置为 .center.left.right.

我直接在图形上下文中绘图。

这是问题所在: 该函数有效,但是 NSMutableParagraphStyle 属性中的 none 被接受。

func text(_ string: String, _ x: CGFloat, _ y: CGFloat) {
     let attributedString = NSAttributedString(string: string,
                                               attributes: attributes)
     attributedString.draw(at: CGPoint(x: x, y: y))
}

attributesparagraphStyle是全局变量:

var paragraphStyle: NSMutableParagraphStyle?
var attributes: [NSAttributedString.Key: Any] = [:]

它们由一个函数设置,该函数在设置更改时调用:

func setTextAttributes() {
    paragraphStyle = NSMutableParagraphStyle()
    
    switch settings.textAlign {
    case .left:
        paragraphStyle?.alignment = .left
    case .right:
        paragraphStyle?.alignment = .right
    case .center:
        paragraphStyle?.alignment = .center
    }
   
    paragraphStyle?.lineSpacing = CGFloat(settings.textLeading)
       
    attributes = [
        .font: UIFont(name: settings.textFont, size: CGFloat(settings.textSize))!,
        .foregroundColor: settings.fill,
        .strokeWidth: -settings.strokeWeight,
        .strokeColor: settings.stroke,
        .paragraphStyle: paragraphStyle!
    ]
}

所有文本设置都存储在一个设置结构中(我将在此处省略)并且我已经在多个断点处检查了 paragraphStyleattributes 的状态,直到文本被绘制。似乎当它进入 NSString 绘制方法时,它只是被忽略了。

这里有一些示例代码写在 API:

line(200, 0, 200, height)
line(0, 120, width, 120)
textAlign(.right)
text("ABCD", 200, 120)
line(0, 200, width, 200)
textAlign(.center)
text("EFGH", 200, 200)
textAlign(.left)
line(0, 280, width, 280)
text("IJKL", 200, 280)

我的输出看起来像这样,所有内容都左对齐(添加的行表明它全部左对齐):

下面或多或少是我希望输出的样子(忽略字体更改):

您可以使用 draw(in:),它允许您指定一个 CGRect 绘图将在其中进行。

在每个对齐方式中,您希望在原点绘制字符串,该原点与传入方法的点的 x 偏移不同。

func text(_ string: String, _ x: CGFloat, _ y: CGFloat) {
     let attributedString = NSAttributedString(string: string,
                                               attributes: attributes)
    let size = attributedString.size()
    let xOffset: CGFloat
    switch attributes[.paragraphStyle]?.alignment ?? .left {
    case .center:
        xOffset = size.width / 2
    case .left:
        xOffset = 0
    case .right:
        xOffset = size.width
    default:
        fatalError("not supported!")
    }
    let rect = CGRect(origin: CGPoint(x: x - xOffset, y: y). size: size)
    attributedString.draw(in: rect)
}