Objective c RTL&;UITextView中的LTR(双向)

Objective c RTL&;UITextView中的LTR(双向),objective-c,uitextview,bidi,Objective C,Uitextview,Bidi,我试图保存UITextView的内容,其中包含RTL和LTR格式的文本行。 问题是UITextView只检查格式化方向的第一个字符。让我们假设我处于“编辑”模式,并编写此文本(_uu表示空格): 在保存之后,我们失去了RTL。现在,我想再次编辑此文本,它现在看起来像: text1_______________________________________ אקסא text2_______________________________________ 我无法在一个UITextV

我试图保存UITextView的内容,其中包含RTL和LTR格式的文本行。 问题是UITextView只检查格式化方向的第一个字符。让我们假设我处于“编辑”模式,并编写此文本(_uu表示空格):

在保存之后,我们失去了RTL。现在,我想再次编辑此文本,它现在看起来像:

text1_______________________________________
אקסא      
text2_______________________________________
我无法在一个UITextView中混合\u200F和\u200E方向字符。
如何管理并正确保存UITextView中的双向文本?

下面是一个快速的概念验证,使用:
-将文本拆分为段落
-对于每个段落,检测主要语言
-为相应范围创建具有正确对齐方式的属性文本

// In a subclass of `UITextView`

+ (UITextAlignment)alignmentForString:(NSString *)astring {
    NSArray *rightToLeftLanguages = @[@"ar",@"fa",@"he",@"ur",@"ps",@"sd",@"arc",@"bcc",@"bqi",@"ckb",@"dv",@"glk",@"ku",@"pnb",@"mzn"];

    NSString *lang = CFBridgingRelease(CFStringTokenizerCopyBestStringLanguage((CFStringRef)astring,CFRangeMake(0,[astring length])));

    if (astring.length) {
        if ([rightToLeftLanguages containsObject:lang]) {
            return NSTextAlignmentRight;
        }
    }

    return NSTextAlignmentLeft;
}

- (void)setText:(NSString *)str { // Override
    [super setText:str];

    // Split in paragraph
    NSArray *paragraphs = [self.text componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];

    // Attributed string for the whole string
    NSMutableAttributedString *attribString = [[NSMutableAttributedString alloc]initWithString:self.text];

    NSUInteger loc = 0;
    for(NSString *paragraph in paragraphs) {

        // Find the correct alignment for this paragraph
        NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc]init];
        [paragraphStyle setAlignment:[WGTextView alignmentForString:paragraph]];

        // Find its corresponding range in the string
        NSRange range = NSMakeRange(loc, [paragraph length]);

        // Add it to the attributed string
        [attribString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:range];

        loc += [paragraph length];
    }

    [super setAttributedText:attribString];
}
此外,我建议阅读以管理更复杂的用例

// In a subclass of `UITextView`

+ (UITextAlignment)alignmentForString:(NSString *)astring {
    NSArray *rightToLeftLanguages = @[@"ar",@"fa",@"he",@"ur",@"ps",@"sd",@"arc",@"bcc",@"bqi",@"ckb",@"dv",@"glk",@"ku",@"pnb",@"mzn"];

    NSString *lang = CFBridgingRelease(CFStringTokenizerCopyBestStringLanguage((CFStringRef)astring,CFRangeMake(0,[astring length])));

    if (astring.length) {
        if ([rightToLeftLanguages containsObject:lang]) {
            return NSTextAlignmentRight;
        }
    }

    return NSTextAlignmentLeft;
}

- (void)setText:(NSString *)str { // Override
    [super setText:str];

    // Split in paragraph
    NSArray *paragraphs = [self.text componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];

    // Attributed string for the whole string
    NSMutableAttributedString *attribString = [[NSMutableAttributedString alloc]initWithString:self.text];

    NSUInteger loc = 0;
    for(NSString *paragraph in paragraphs) {

        // Find the correct alignment for this paragraph
        NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc]init];
        [paragraphStyle setAlignment:[WGTextView alignmentForString:paragraph]];

        // Find its corresponding range in the string
        NSRange range = NSMakeRange(loc, [paragraph length]);

        // Add it to the attributed string
        [attribString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:range];

        loc += [paragraph length];
    }

    [super setAttributedText:attribString];
}