RTL & LTR (двунаправленный) в UITextView
Я пытаюсь сохранить содержимое UITextView, который содержит строки текста в формате RTL и LTR. Проблема в том, что UITextView проверяет только первый символ для форматирования направления. Давайте предположим, что я нахожусь в режиме "редактирования" и напишем этот текст (__ означает пробелы):
text1_______________________________________
____________________________________________אקסא
text2_______________________________________
и после сохранения мы потеряли RTL для אקסא. Теперь я хотел бы еще раз отредактировать этот текст, который теперь выглядит так:
text1_______________________________________
אקסא
text2_______________________________________
Я не могу смешивать символы направления в одном UITextView. Как это сделать и правильно сохранить двунаправленный текст из UITextView?
1 ответ
Вот краткое доказательство концепции с использованием NSAttributedString
:
- Разделить текст на абзацы
- для каждого абзаца определить основной язык
- Создать атрибутивный текст с правильным выравниванием для соответствующего диапазона
// 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];
}
Кроме того, я рекомендую прочитать алгоритм Unicode BiDi для управления более сложными вариантами использования.