15

我想将标签设置为字符串:“خخخ 刚刚购买:伪装工具包。” 但是当我运行测试时,标签显示“。刚刚购买:伪装工具包خخخ”?

如果文本不是以阿拉伯语开头,它将显示为我设置的内容。有什么问题?

有人知道如何处理这个问题吗?

4

3 回答 3

43

首先,阅读 Cal Henderson 出色的“理解 Unicode 中的双向 (BIDI) 文本”。.

信不信UILabel由你,按照你要求的方式进行布局。您提供了一个从右到左的字符串(以阿拉伯语开头)。它开始从右到左显示。然后,您嵌入了一个从左到右的英文字符串,它从左到右排列。然后它会看到句点,并将其从右到左排列,因为这是一个阿拉伯字符串,恰好包含一些英语(正如最好的说法UILabel)。

你想要的是一个嵌入了阿拉伯语的从左到右的字符串。这意味着您必须以从左到右的字符开始字符串。两个选项:在开头添加一些英文,或者使用零宽度的从左到右标记(U+200E,LRM)将字符串的开头锚定为 LTR 模式。

目标-C:

self.label.text = @"\u200eكتب just bought: Disguise Kit.";

迅速:

self.label.text = "\u{200E}كتب just bought: Disguise Kit."

关于 U+200E 的好消息是,您可以在显示之前安全地将其添加到每个 LTR 字符串中。您甚至可以安全地将其放在 LTR 语言的本地化字符串的开头。如果它是多余的,它不会伤害任何东西。

还有一些需要注意的事情:永远不要用ككك测试这些东西,总是用كتب(就像每个好学生:D)或更好的东西,比如الو。否则,您无法判断阿拉伯语何时向后布局。我喜欢الو,因为它向后看起来完全不同。

另外,在测试时,请注意 Xcode 不知道如何布局阿拉伯语。因此,如果您在代码中编写任何静态字符串,它们将在编辑器中向后显示,但它们会在 UI 中正确显示。让我发狂。


请务必查看 guru_meditator 对 iOS 10+/macOS 10.12 中添加的有用相关功能的回答

于 2012-09-28T02:52:39.637 回答
4

由于 iOS 10(和 macOS 10.12)String localizedStringWithFormat在占位符周围插入 Unicode 隔离。这是使用混合语言方向格式化字符串的高级方法,无需手动插入方向标记。

String.localizedStringWithFormat("%@ just bought: Disguise Kit.", "خخخ")
// "⁨خخخ⁩ just bought: Disguise Kit."

相比于:

String(format: "%@ just bought: Disguise Kit.", "خخخ")
// ".just bought: Disguise Kit خخخ"

要查看localizedStringWithFormat 正在做什么:

let scalars = String.localizedStringWithFormat("%@ just bought: Disguise Kit.", "خخخ")
    .unicodeScalars.map { "U+\(String(format: "%04X", $0.value))" }
print(scalars)
// ["U+2068", "U+062E", "U+062E", "U+062E", "U+2069", "U+0020", ...

其中 U+2068 是 FIRST STRONG ISOLATE,U+2069 是 POP DIRECTIONAL ISOLATE。您可以阅读更多关于隔离的信息:https ://www.unicode.org/reports/tr9/tr9-41.html#Explicit_Directional_Isolates

此功能在WWDC 2016 会议 232 国际用户界面中的新增功能中引入

于 2019-04-08T09:15:20.113 回答
0

实际上, \u{200E} (或任何)符号可以插入到字符串文字中。

  1. 添加“Unicode Hex Input”(系统偏好设置 -> 键盘 -> 输入源 -> + -> Unicode Hex Input)。
  2. 在文本编辑器中,将光标移动到要插入符号的位置。
  3. 将输入源切换到“Unicode Hex Input”。
  4. 按住 Option 键并键入 200E。
  5. 应该插入符号并且字符串应该看起来像您期望的那样。
于 2020-04-29T15:22:36.203 回答