我想给一个字符串设置标签:"خخخ just bought: Disguise Kit.",但是当我运行测试时,标签显示为".just bought: Disguise Kit خخخ"?
如果文本不以阿拉伯语开头,则会按照我设置的方式显示。 问题出在哪里?
有谁知道如何处理这个问题吗?
我想给一个字符串设置标签:"خخخ just bought: Disguise Kit.",但是当我运行测试时,标签显示为".just bought: Disguise Kit خخخ"?
如果文本不以阿拉伯语开头,则会按照我设置的方式显示。 问题出在哪里?
有谁知道如何处理这个问题吗?
首先,阅读Cal Henderson杰出的 "Understanding Bidirectional (BIDI) Text in Unicode."。
不管你相信与否,UILabel
是按照你要求的方式进行布局的。你提供了一个从右到左的字符串(从阿拉伯语开始)。它从右到左开始显示。然后你嵌入了一个从左到右的英文字符串,它会从左到右进行布局。然后,它看到了句号,并由于这是一个包含一些英文的阿拉伯字符串(尽可能地由UILabel
判断),所以它进行了从右到左的布局。
你想要的是一个从左到右的包含阿拉伯字符的字符串。这意味着你必须用从左到右的字符开始字符串。有两个选项:在开头添加一些英文或使用零宽度的从左到右标记(U+200E,LRM)将字符串的开头锚定到LTR模式。
Objective-C:
self.label.text = @"\u200eكتب just bought: Disguise Kit.";
Swift:
->Swift:
self.label.text = "\u{200E}كتب just bought: Disguise Kit."
关于 U+200E 的好消息是,在显示之前,您可以安全地将其添加到每个 LTR 字符串中。您甚至可以安全地将其放在 LTR 语言的本地化字符串的开头。如果它是冗余的,则不会造成任何损害。
还有几件事情需要注意:永远不要使用ككك测试这些内容,而应该始终使用كتب(就像每个好学生一样:D),或者最好像الو这样完全相反的东西。否则,你无法判断阿拉伯语是否以反向方式布局。我喜欢 الو,因为反过来看完全不同。
另外,在测试时,请注意 Xcode 不知道如何布局阿拉伯语。所以,如果您在代码中编写任何静态字符串,它们将在编辑器中以反向方式显示,但在 UI 中将正确显示。这让我发疯。
请务必查看 guru_meditator 的答案,了解 iOS 10+/macOS 10.12 中添加的有用相关功能。
\U200F
:D - Konstantinos NatsiosString localizedStringWithFormat
在占位符周围插入Unicode隔离符号。这是一种更高级的字符串格式化方式,可混合使用多种语言方向,无需手动插入方向标记。String.localizedStringWithFormat("%@ just bought: Disguise Kit.", "خخخ")
// "خخخ just bought: Disguise Kit."
与之比较:
String(format: "%@ just bought: Disguise Kit.", "خخخ")
// ".just bought: Disguise Kit خخخ"
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代表首个强制隔离符,U+2069代表弹出方向隔离符。有关隔离符的更多信息,请参阅: https://www.unicode.org/reports/tr9/tr9-41.html#Explicit_Directional_Isolates
此功能是在WWDC 2016 232国际用户界面的新功能中引入的。