In Xcode, how to display text merging English+Arabic and beginning with Arabic?

女生的网名这么多〃 提交于 2019-12-03 03:20:09

问题


I want to set a label to string: "خخخ just bought: Disguise Kit." but when I run the test, the label show ".just bought: Disguise Kit خخخ"?

If the text is not begin with Arabic, It will show as what I set. What's the problem?

Does anybody know how to deal with this issue?


回答1:


First, read Cal Henderson's excellent "Understanding Bidirectional (BIDI) Text in Unicode.".

Believe it or not, UILabel is laying it out the way you asked. You've provided a right-to-left string (starting in Arabic). It starts displaying that right to left. You then embedded a left-to-right English string, which it lays out left to right. It then sees the period, and lays that out right-to-left since this is an Arabic string that just happens to have some English in it (as best UILabel can tell).

What you meant to have is a left-to-right string with Arabic embedded. That means you have to start the string with left-to-right characters. Two options: add some English to the start, or use the zero-width Left-to-Right Mark (U+200E, LRM) to anchor the beginning of the string into LTR mode.

Objective-C:

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

Swift:

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

The good news about U+200E is that you can safely add it to every LTR string before you display it. You can even safely put it at the start of your localized strings for LTR languages. If it's redundant, it doesn't hurt anything.

A couple of other things to note: never test this stuff with ككك, always test with كتب (like every good student :D) or better yet something like الو. Otherwise you can't tell when the Arabic is laid out backwards. I like الو because it looks wildly different backwards.

Also, when testing, note that Xcode doesn't know how to layout Arabic. So if you write any static strings in your code, they'll be displayed backwards in the editor, but they'll display correctly in the UI. Drives me crazy.




回答2:


Since iOS 10 (and macOS 10.12) String localizedStringWithFormat inserts Unicode isolates around placeholders. This is a higher level way to format strings with mixed language direction, without manually inserting directional marks.

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

Compare to:

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

To see what localizedStringWithFormat is doing:

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", ...

Where U+2068 is FIRST STRONG ISOLATE, and U+2069 is POP DIRECTIONAL ISOLATE. You can read more about isolates in: https://www.unicode.org/reports/tr9/tr9-41.html#Explicit_Directional_Isolates

This feature was introduced in WWDC 2016 session 232 What's New in International User Interfaces



来源:https://stackoverflow.com/questions/12366330/in-xcode-how-to-display-text-merging-englisharabic-and-beginning-with-arabic

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!