改变UITextView的文本方向

13

我的语言在iOS上默认不支持Unicode,所以我正在使用UITextView上的内嵌TrueType字体。它基本上可以工作,但是我的问题类似于阿拉伯语和希伯来语,我的语言是从右到左书写的。因此,我需要更改文本的方向(而不是文本对齐方式)。

我进行了一些搜索,它们都涉及NSLocale等内容,但是它能否在代码中更改?如果我可以将其更改为阿拉伯语/希伯来语之类的东西,那么它可能会起作用,但应该在代码中完成,因为我不想更改手机的语言。

那么,对于文本输入,我真正的选择是什么?任何帮助将不胜感激。

谢谢。


我也想实现和你一样的功能。我想要实现一个从右到左文本方向的乌尔都语键盘。所以,你有找到任何获取带有RTL文本方向的自定义键盘字符的方法吗(正如你在已接受答案下的评论中提到的)?如果是**的话,请在这里分享代码。我也陷入了和你一样的困境,请帮帮我。 - Bhavin
请点击这里的链接以获取SWIFT中此问题的解决方案:[https://dev59.com/Gm445IYBdhLWcg3wWZAU#41424462] - Dr.Ax
7个回答

9
您可以在文本视图的每行开头放置一个“从右到左嵌入”的Unicode字符。
名称:RIGHT-TO-LEFT EMBEDDING Unicode:202B UTF8:E2 80 AB
请注意,此字符是不可见的(没有形状)。
以下代码将行末字符替换为EOL + RTL_EMBEDDING字符串:
appDescription.text = [rtlDescriptionString stringByReplacingOccurrencesOfString:@"\n" withString:@"\n‫;["

7

您的问题真的很有趣。所以在一个小时内,我想出了一个解决方案。它远非完美,但您可以使用它并修复剩余的错误。 这是一个带有文本视图的简单视图控制器。您可以通过输入文本来添加文本,也可以使用

设置其值。
-(void) setText:(NSString*) txt;

以下是代码:

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

希望这对你有帮助 =)

非常有用,我尝试使用它与此自定义键盘一起使用:https://github.com/kulpreetchilana/Custom-iOS-Keyboards 但是我得到了默认的方向。请问您能否帮忙将您的代码与此自定义键盘控件集成或提供任何类似的建议,只是想获取RTL文本方向的自定义键盘字符。谢谢。 - hafedh
@Max:我也想实现和hafedh一样的功能。我想要实现一个从右到左乌尔都语键盘。所以,你有找到任何获取带有RTL文本方向的自定义键盘字符的方法吗(正如hafedh所提到的)?如果是,请在此处分享代码。我也陷入了类似的困境。请帮帮我。 - Bhavin

4

只需使用Unicode 202B字符进行从右到左的嵌入。

示例:

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


0

对我来说,直接将\u202B添加到.strings文件的字符串中并没有奏效(最终结果会直接打印出“202B”部分)。但是,在从调用localizedStringForKey返回字符串后再将\u202B添加到字符串中确实奏效。

因此,我的解决方案是:我在.strings文件中直接插入任意字符串“RLE_SYMBOL”,然后在调用localizedStringForKey后,将“RLE_SYMBOL”替换为“\u202B”。

这有点间接,不是最好的解决方案,但是是一个快速的解决方案。

   mystring = [mystring stringByReplacingOccurrencesOfString:@"RLE_SYMBOL" withString:@"\u202B"];

0

你好,我认为通过使用带有HTML和CSS的UIWebView可以完成这项工作。


UIWebView仅用于显示内容。 - Jinah Adam

0

我一直面临着同样的问题。我的语言类似于阿拉伯语,从右到左书写。对我来说最简单的解决方案是将文本对齐方式更改为右侧,并在输入每个字符后将光标移动到左侧。这适用于SWIFT 3.0。

func textViewDidChange(_ textView: UITextView) {

    let newPosition = myTextView.beginningOfDocument
    myTextView.selectedTextRange = myTextView.textRange(from: newPosition, to: newPosition)

    print(myTextView.text)


    return

}

-3

iPhone无法正确显示希伯来语和其他从右到左的文本,因此我认为您无法改变文本的方向。


我以前显示阿拉伯文本没有遇到过问题,我认为希伯来文也是一样的,但是我不能确定文本输入是否有问题。 - Jinah Adam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接