UILabel lineBreakMode 设置为 .ByTruncatingTail 导致 RTL 阿拉伯语文本显示不正确

UILabel lineBreakMode set to .ByTruncatingTail causes RTL arabic text to appear incorrectly

我有一个 UILabel,里面有 RTL 阿拉伯语文本。只要我不更改 lineBreakMode,一切都会正确显示。我需要它来剪辑而不是 byTruncatingTail 以避免显示省略号字符,因为我试图在左边缘显示渐变蒙版。

我试过更改 contentModealignment 等,但无济于事。标签的右侧似乎是从中间某处开始文本,而不是从头开始(即文本中最右边的字符)。

这是我看到的 lineBreakMode = .byClipping

这就是我删除 lineBreakMode

时看到的内容

这是代码

let arabicLabel = UILabel(frame: .zero)
arabicLabel.semanticContentAttribute = .forceRightToLeft
arabicLabel.numberOfLines = 1
//arabicLabel.lineBreakMode = .byClipping
arabicLabel.text = "عِنْدَمَا1 عِنْدَمَا2 عِنْدَمَا3 عِنْدَمَا4 عِنْدَمَا5 عِنْدَمَا6 قَدِمْتُ عَلَى (صَاحِبِي) عِنْدَمَا7 عِنْدَمَا8 عِنْدَمَا9 عِنْدَمَا10 عِنْدَمَا عِنْدَمَا قَدِمْتُ عَلَى (صَاحِبِي)"
arabicLabel.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(arabicLabel)

在这上面浪费了足够的时间之后,我结束了 丑陋的 方式,通过覆盖 drawText 并添加任意数量的填充以有效隐藏省略号字符并为 RTL 和 LTR 处理它。我可以改为基于 semanticContentAttributes,但在我的例子中,标签只有在包含 RTL 文本时才会右对齐。我还必须覆盖 text 以自动检测主要语言集,并自动更改对齐方式。

  public override func drawText(in rect: CGRect) {
    let extraWidth = fadeLength + 50
    var newRect = rect

    if self.textAlignment == .right {
      newRect.origin.x -= extraWidth
      newRect.size.width += extraWidth
    } else {
      newRect.size.width += extraWidth
    }

    super.drawText(in: newRect)
  }