Arabic Text Alignment
you can try this code:
let currentDeviceLanguage = Locale.current.languageCode
if let currentDeviceLanguage = Locale.current.languageCode {
print("currentLanguage", currentDeviceLanguage)
if currentDeviceLanguage == "he" {
UIView.appearance().semanticContentAttribute = .forceRightToLeft
} else {
UIView.appearance().semanticContentAttribute = .forceLeftToRight
}
}
UItextView arabic text aligned to right
You can set the writing direction of a UITextView using the setBaseWritingDirection selector:
UITextView *someTextView = [[UITextView] alloc] init];
[someTextView setBaseWritingDirection:UITextWritingDirectionLeftToRight forRange:[someTextView textRangeFromPosition:[someTextView beginningOfDocument] toPosition:[someTextView endOfDocument]]];
The code is a little tricky because UITextView supports having different parts of the text with different writing directions. In my case, I used [someTextView textRangeFromPosition:[someTextView beginningOfDocument] toPosition:[someTextView endOfDocument]] to select the full text range of the UITextView. You can adjust that part if your needs are different.
You may also want to check whether the text in your UITextView is LTR to RTL. You can do that with this:
if ([someTextView baseWritingDirectionForPosition:[someTextView beginningOfDocument] inDirection:UITextStorageDirectionForward] == UITextWritingDirectionLeftToRight) {
// do something...
}
Note that I specified the start of the text using [someTextView beginningOfDocument] and searched forward using UITextStorageDirectionForward. Your needs might differ.
If you subclass UITextView replace all these code samples with "self" and not "someTextView", of course.
I recommend reading about the UITextInput protocol, to which UITextView conforms, at http://developer.apple.com/library/ios/#documentation/uikit/reference/UITextInput_Protocol/Reference/Reference.html.
Warning about using the textAlignment property in iOS 5.1 or earlier: if you use it with this approach together with setting the base writing direction, you will have issues because RTL text when aligned left in a UITextView actually aligns to the right visually. Setting text with an RTL writing direction to align right will align it to the left of the UITextView.
why (arabic with english) text refuses to align right?
Unicode has two marker characters (LTR: 0x200E, RTL:200F). These are invisible, but control the direction, I just need to add this \u{200E}
to force the wrapping direction.
\u{200E} \(word1) found your review on \(word2) useful.
EDIT:
see full tutorial here, for more info.
Change the UITextView Text Direction
You question have really interested me. So in a matter of hour I've came up with solution. It is far from perfect, but you can use it and fix remaining bugs.
This is a simple view controller with text view. You can add text typing it or you can set the value using
-(void) setText:(NSString*) txt;
So here is the code:
ReverseTextVC.h
@interface ReverseTextVC : UIViewController <UITextViewDelegate> {
NSMutableArray* _lines;
UITextView* _tv;
}
/**
Returns reversed text.
The lines is also updated. This array contains all lines. You should pass this array again if you want to append the text.
*/
+(NSString*) reverseText:(NSString*) text withFont:(UIFont*) font carretPosition:(NSRange*) cpos Lines:(NSMutableArray*) lines Bounds:(CGRect) bounds;
-(void) setText:(NSString*) txt;
@end
ReverseTextVC.m
@implementation ReverseTextVC
-(id) init {
if( self = [super init] ) {
_tv = [[UITextView alloc] initWithFrame: CGRectMake(0, 0, 320, 480)];
_tv.textAlignment = UITextAlignmentRight;
_tv.delegate = self;
[self.view addSubview: _tv];
[_tv release];
_lines = [[NSMutableArray alloc] initWithCapacity: 10];
[_lines addObject: [NSMutableString stringWithCapacity: 255]];
}
return self;
}
-(void) dealloc {
[_lines release];
[super dealloc];
}
-(void) loadView {
UIView* v = [[UIView alloc] initWithFrame: CGRectMake(0, 20, 320, 480)];
self.view = v;
[v release];
}
-(void) setText:(NSString*) txt {
NSString* result = nil;
NSRange rng;
NSArray* words = [txt componentsSeparatedByString: @" "];
//we should do it iteratively (cause it's the simplest way =) )
for(NSString* word in words) {
word = [NSString stringWithFormat: @"%@ ", word];
for(int i=0; i<[word length]; ++i) {
NSRange r; r.length = 1; r.location = i;
result = [ReverseTextVC reverseText: [word substringWithRange: r]
withFont: _tv.font
carretPosition: &rng
Lines: _lines
Bounds: _tv.bounds];
}
}
_tv.text = result;
}
#pragma mark -
#pragma mark UITextViewDelegate
-(BOOL) textView:(UITextView*) textView shouldChangeTextInRange:(NSRange) range replacementText:(NSString*) text {
NSRange rng;
textView.text = [ReverseTextVC reverseText: text
withFont: textView.font
carretPosition: &rng
Lines: _lines
Bounds: textView.bounds];
textView.selectedRange = rng;
return NO;
}
#pragma mark -
#pragma mark Static
+(NSString*) reverseText:(NSString*) text withFont:(UIFont*) font carretPosition:(NSRange*) cpos Lines:(NSMutableArray*) lines Bounds:(CGRect) bounds {
cpos->length = 0;
cpos->location = 0;
if( [text length] ) {
if( ![text isEqualToString: @"\n"] ) {
[(NSMutableString*)[lines lastObject] insertString: text
atIndex: 0];
} else {
[lines addObject: [NSMutableString stringWithCapacity: 255]];
}
} else {
//backspace
//TODO:
NSRange del_rng;
del_rng.length = 1;
del_rng.location = 0;
if( [(NSMutableString*)[lines lastObject] length] ) {
[(NSMutableString*)[lines lastObject] deleteCharactersInRange: del_rng];
}
if( ![(NSMutableString*)[lines lastObject] length] ) {
[lines removeLastObject];
}
}
CGSize sz = [(NSString*)[lines lastObject] sizeWithFont: font];
if( sz.width >= bounds.size.width-15 ) {
NSMutableArray* words = [NSMutableArray arrayWithArray: [(NSString*)[lines lastObject] componentsSeparatedByString: @" "]];
NSString* first_word = [words objectAtIndex: 0];
[words removeObjectAtIndex: 0];
[(NSMutableString*)[lines lastObject] setString: [words componentsJoinedByString: @" "]];
[lines addObject: [NSMutableString stringWithString: first_word]];
}
NSMutableString* txt = [NSMutableString stringWithCapacity: 100];
for(int i=0; i<[lines count]; ++i) {
NSString* line = [lines objectAtIndex: i];
if( i<([lines count]-1) ) {
[txt appendFormat: @"%@\n", line];
cpos->location += [line length]+1;
} else {
[txt appendFormat: @"%@", line];
}
}
return txt;
}
@end
Hope it helps you =)
Non-Editable UITextView Left-Aligns RTL (Arabic, Hebrew, etc) Text
Solved it! Turns out it's very simple: just set the textAlignment to UITextAlignmentRight.
UITextView works differently when editable and not, especially when it comes to RTL text. If the base writing direction is RTL in an editable text view, you must align the text left, not right, in order for the text to actually align right (the RTL writing direction flips the defaults!)
So, when you have a UITextView, you may want to first check the editable property and then use the writing direction of the first character (this is how iOS determines whether the text is aligned left or right) to set the textAlignment property.
For example:
// check if the text view is both not editable and has an RTL writing direction
if (!someTextView.editable && [someTextView baseWritingDirectionForPosition:[someTextView beginningOfDocument] inDirection:UITextStorageDirectionForward] == UITextWritingDirectionRightToLeft) {
// if yes, set text alignment right
someTextView.textAlignment = UITextAlignmentRight;
} else {
// for all other cases, set text alignment left
someTextView.textAlignment = UITextAlignmentLeft;
}
}
UPDATE FOR iOS 6:
In iOS 6, a UITextView's textAlignment property actually corresponds to its appearance on the screen. For iOS 6, just set the textAlignment to the direction you want to see it. The above code works as described for iOS 5.1 and earlier.
I hope this helps anyone else dealing with this issue!
Links not working in UITextView Attributed String when language is Arabic
I got the issue.
I have been overriding the
func point(inside point: CGPoint, with event: UIEvent?) -> Bool
method to ignore the taps anywhere but not the links in a textview.
I was using a UITextLayoutDirection as left inside this method. I had to change it according to the alignment for different languages. That is for Right to Left languages, I will use the UITextLayoutDirection.Right.
Thanks
Related Topics
How to Stretch a View to Its Parent Frame with Swiftui
How to Enable a Button in Different Cases in Swift
How to Query Firebase Data Childbyautoid
Xcode 6.1 Swift Extensions - Sourcekit Service Crash
Rxswift + Mvvm + Coordinator Pattern, How to Wait for Coordinator Result Sequentially
Way to Check If Up or Down Button Is Pressed with Nsstepper
List Scroll Freeze on Catalyst Navigationview
Editable Nstextview from Interface Builder
Add New Card Is Not Being Called in Stripe Paymentoptionviewcontroller
Realitykit - Add Force to Entity at Specific Point
Occasional Blank Frames After Exporting Asset - Avexportsession
Swiftui Previews - Unexpected Data
Filtering an Array Inside a Dictionary - Swift
How to Horizontally Center Content of Horizontal Scrollview
Appdelegate#Applicationdidfinishlaunching Not Called for Swift 4 Macos App Built from Command Line
Xcode9/Scenekit - .Dae File Not Loading into Scnscene - Returns Nil
How to Delay a for Loop in Swift Without Interrupting The Main Thread
Os X App Doesn't Launch New Window on Dock Icon Press in Swift