Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change the UITextView Text Direction

my language is not supported by iOS by default, so unicode is not an option so i am using a embedded true type font on a UITextView

it works for the most part, but my issue is like Arabic, and Hebrew my language is written from right to left. So i need to change the direction of the text (Not Text Alignment).

i did some searches, they all talk about NSLocale and stuff, but can it be changed in code? if i can change it to something like Arabic/Hebrew it would work i guess, but it should be done in code, because i dont want change the language of the phone.

so what really are my options for text input? any help would be appreciated.

Thanks.

like image 821
Jinah Adam Avatar asked Feb 05 '11 06:02

Jinah Adam


3 Answers

You can place a "right-to-left embedding" Unicode character at start of each line in the text view.

Name: RIGHT-TO-LEFT EMBEDDING Unicode : 202B UTF8 : E2 80 AB

Note that this character is invisible (No shapes).

The following piece of code replaces the end-of-line characters with a EOL+RTL_EMBEDDING string :

appDescription.text = [rtlDescriptionString stringByReplacingOccurrencesOfString:@"\n" withString:@"\n‫;["
like image 89
Ali Nadalizadeh Avatar answered Oct 11 '22 19:10

Ali Nadalizadeh


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 =)

like image 37
Max Avatar answered Oct 11 '22 21:10

Max


just use the Unicode 202B character for RIGHT-TO-LEFT EMBEDDING.

Example:

uiTextView.text = [NSString stringWithFormat:@"\u202B%@",textString];

like image 4
Almog C Avatar answered Oct 11 '22 20:10

Almog C