Left-To-Right Mark not working in Swift
The below should be a comment on the question, really, but I need the formatting...
I do this in a Playground (Xcode 7 beta 4)
let value = "32.12%"
print("نسبة ط:\u{200E}\(value)")
And it prints
32.12% :نسبة ط
Is that what you want?
Also
let value = "\u{200E}32.12%"
print("نسبة ط:\(value)")
works the same. This is in the Playground. Are you using an older version of Xcode perhaps?
Right to left UILabels
Have a look at this SO, it contains some info on this subject that might help you out.
It seems to work for some by adding the code \u200F to the strings to be displayed.
NSString *RTFstr = "1. בבוקר"; //This could be any right-to-left string
NSString *directionalString = [@"\u200F" stringByAppendingString:[note text]];
[someUITextView setString:directionalString];
Weird behaviour on joining mixed right-to-left and left-to-right language strings
This is caused by the Unicode BIDI (Bidirectional Text) algorithm. First, I'll explain how to fix it, since it's fairly straightforward, then I'll explain what's happening in case you want more information.
You need to add LTR (Left-To-Right Mark) characters at each place you want to reset the text direction to be LTR. In your case that's at the start of the string and at the start of each |
block:
let ltr = "\u{200e}"
let tempText = ltr + tempTextArray.joined(separator: "\(ltr) | ")
// => זה מבחן | 7 x 5 abc | other text
If you're going to do work with Hebrew, you absolutely want to read Cal Henderson's fantastic explanation of the algorithm: Understanding Bidirectional (BIDI) Text in Unicode.
Now to explain what's happening. You're printing a single string whose first character is the ז
in "זה מבחן," and last character is the final t
in "text." It is not three strings separated by |
, it's just one long string. When you display that string, and the BIDI algorithm has to decide where all the characters go.
The first character (ז) is a RTL character, so it decides that this is a RTL string that has some LTR text embedded. That's the opposite of what you want. You want this to be a LTR string with some RTL text embedded. So you need to start with a LTR character such as Left-To-Right Mark.
The BIDI algorithm's job is to tell the system in which direction the next character should go. Each of the characters in זה are RTL, so that's easy, keep going left. But what about the space between זה and מבחן? Space is neutral in direction, and the last character was RTL, so the space goes to the left. But then we come to the space between מבחן and |. Space is neutral and | is neutral, so the BIDI algorithm would put the space and | to the left again. You want the space and | to be LTR, so you need to add another LTR character there.
7 is also neutral, but x
is LATIN SMALL LETTER X which is LTR (not MULTIPLICATION X which is neutral).
The final result is that the BIDI algorithm decides this is a RTL string that begins 7 | זה מבחן
and then is followed (to the left) by an embedded LTR string x 5 abc | other text
. (In other words, this is a Hebrew string that happens to have some English in it, not an English string that happens to have some Hebrew.)
I expect what's actually displayed in your question above isn't what you're seeing (because of how BIDI algorithms get applied on Stack Overflow). I expect it actually looks like this:
And if you read this right to left, it should make more sense now what's happening.
Text direction with print or println in Swift for mixed text
It looks like I found the answer. Adding "\u{200E}", the Left to Right Mark before the character resolves the issue.
More here: http://en.wikipedia.org/wiki/Left-to-right_mark
UITextView right to left Unicode \u202B not working
The notation \u202b
denotes the Unicode character U+202B is RIGHT-TO-LEFT EMBEDDING, which does not affect the writing direction of characters with strong directionality, such as Latin letters.
The character U+202E RIGHT-TO-LEFT OVERRIDE (\u202e
) forces right-to-left writing direction, overriding the inherent directionality of characters. To end its effect, use the U+202C POP DIRECTIONAL FORMATTING character:
'\u202eHello There\nMy name is Mark \u202c'
This has little to do with fonts. The rendering engine is supposed to handle some characters like “(” using mirrored symbols, e.g. so that “(foo)” gets rendered as “(oof)” and not “)oof(” in right-to-left writing. But generally, no mirroring is involved; letters remain the same, they just run right to left.
If you actually want to have text mirrored, you need something completely different (a transformation).
How to know if language is right-to-left in SwiftUI?
Here is Locale
based approach:
guard let language = Locale.current.languageCode else { return }
let direction = Locale.characterDirection(forLanguage: language)
switch direction {
case .leftToRight:
print("do something here")
case .rightToLeft:
print("do something here")
// ... others if needed
default:
print("do something here")
}
iOS: Determine if device language is Right to Left (RTL)
In iOS 9 one can determine the current direction for each individual view.
if #available(iOS 9.0, *) {
if UIView.userInterfaceLayoutDirection(
for: myView.semanticContentAttribute) == .rightToLeft {
// The view is shown in right-to-left mode right now.
}
} else {
// Use the previous technique
if UIApplication.shared.userInterfaceLayoutDirection == .rightToLeft {
// The app is in right-to-left mode
}
}
This is the recommended way of determining the layout direction in iOS 9.
WWDC 2015 video New UIKit Support for International User Interfaces. After minute 31:20.
How to implement a left or right DragGesture() that trigger a switch case in SwiftUI?
You should compare old and new locations instead:
if value.startLocation.x > value.location.x {
print("Swipe Left")
} else {
print("Swipe Right")
}
So the refactored version of your code would be:
struct ContentView: View {
enum SwipeHorizontalDirection: String {
case left, right, none
}
@State var swipeHorizontalDirection: SwipeHorizontalDirection = .none { didSet { print(swipeHorizontalDirection) } }
var body: some View {
VStack {
Text(swipeHorizontalDirection.rawValue)
}
.gesture(
DragGesture()
.onChanged {
if $0.startLocation.x > $0.location.x {
self.swipeHorizontalDirection = .left
} else if $0.startLocation.x == $0.location.x {
self.swipeHorizontalDirection = .none
} else {
self.swipeHorizontalDirection = .right
}
})
}
}
Related Topics
How to Programmatically Open Apple Watch Companion App from iOS App
How Is a Swift Cgvector Created with Dx and Dy (Derivative)
iOS UIlabel Autoshrink So Word Doesn't Truncate to Two Lines
How to Prevent Duplicates in Realmswift List
I Get Nil When Using Nsdateformatter in Swift
Uiwindow? Does Not Have Member Named Bounds
Preventing Erasure of User Data While Upgrading iOS Application via Itunes
Check the Position of the Xcuielement on Screen While Testing iOS Application Using Xctest
Adaptive Launch Screen Storyboards: How to Differentiate iPad Orientations
Xcode UI Tests Can't Find Views That Are Added Programmatically
Pass Extra Argument for UItapgesturerecognizer with Selector
Display: Flex; Doesn't Work on iPad (Both Chrome and Safari)
How to Open Application Using Url
Resize All Subview in Scrollviewdidzoom
Selecting All The Items in UIcollectionview iOS, Even The Cells That Are Not Visible
How to Programmatically Delete My Own iOS App
How to Print Out(Nslog) The Properties of a Custom Object Added to a Nsmutablearray
Upgrading to Swfit 3: Cannot Override 'Init' Which Has Been Marked Unavailable