【问题标题】:NSMutableParagraphStyle is ignored with UIKit's NSString draw methodNSMutableParagraphStyle 被 UIKit 的 NSString 绘制方法忽略
【发布时间】:2021-11-11 22:22:33
【问题描述】:

我正在尝试为 iOS/iPadOS 框架创建一个简单的 text() 函数,该框架仅在屏幕上的坐标处显示文本。它支持全局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))
}

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 draw 方法时,它只是被忽略了。

下面是一些用 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)

我的输出看起来像这样,所有的东西都是左对齐的(添加的行表明它都是左对齐的):

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

【问题讨论】:

  • 你能展示你的预期输出吗?
  • @Sweeper 我添加了预期行为的图像。

标签: ios swift uikit nsstring


【解决方案1】:

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

【讨论】:

  • 这很好并解决了问题,但要确保我理解问题的根本原因:UIKit 和 NSString 绘制方法在添加为参数时是否不遵守 NSMutableParagraphStyle?这就是我的方法不起作用的原因吗?
  • @rikitikitavi draw(at:) 有点笨,总是使用左对齐。 draw(in:) 确实尊重对齐方式,但它接受 CGRect。它将在该矩形内正确对齐文本。用多行文本试试这个,你会看到区别。单行,没有太多要对齐的,是吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-18
  • 1970-01-01
  • 2018-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多