首页 > 解决方案 > NSMutableParagraphStyle 被 UIKit 的 NSString 绘制方法忽略

问题描述

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

我直接绘制到图形上下文。

这就是问题所在:该功能有效,但没有一个NSMutableParagraphStyle属性被兑现。

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

attributes并且paragraphStyle是全局变量:

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!
    ]
}

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

以下是用 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)

我的输出看起来像这样,所有的东西都是左对齐的(添加的行表明它都是左对齐的): 带有意外文本布局输出的 iPad 模拟器的屏幕截图。

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

在此处输入图像描述

标签: iosswiftuikitnsstring

解决方案


您可以使用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)
}

推荐阅读