Подтвердить что ты не робот

AutoLayout + RTL + выравнивание текста UILabel

Я, наконец, собираюсь бороться с Auto Layout и не могу понять, как получить поддержку справа налево (RTL), чтобы работать так, как я ожидал/хочу...

Я разработал представление в Interface Builder, как показано ниже:

IB

В результате приложение работает как ожидается при использовании английского языка:

English

Однако при переключении на RTL-язык (в данном случае арабский) весь просмотр переворачивается (что отлично), но текст UILabel по-прежнему выравнивается по левому краю. Я ожидаю, что он будет выровнен по правому краю, чтобы поддерживать его против UIImageView.

Arabic

Очевидно, что я что-то упускаю и/или это не покрывается Автоманией.

Я должен установить textAlignment вручную при использовании языка RTL?

4b9b3361

Ответ 1

Вы хотите NSTextAlignmentNatural. Это указывает выравнивание текста с загруженного языка приложения ( не из script).

Для iOS 9 и более поздних версий (с использованием Xcode 7) вы можете установить это в раскадровке (выберите параметр --- выравнивания). Если вам нужно настроить таргетинг на более ранние версии, вам необходимо создать выход на метку и установить выравнивание в awakeFromNib.

- (void)awakeFromNib {
    [[self label] setTextAlignment:NSTextAlignmentNatural];
}

Ответ 2

Для меня эти решения не помогли, и я закончил тем, что делал что-то довольно уродливое, но это единственное, что помогло мне. Я добавил его как категорию NSString:

NSString + Extras.h:

#import <Foundation/Foundation.h>

@interface NSString (Extras)
- (NSTextAlignment)naturalTextAligment;
@end

NSString + Extras.m:

#import "NSString+Extras.h"

@implementation NSString (Extras)

- (NSTextAlignment)naturalTextAligment {
    NSArray *tagschemes = [NSArray arrayWithObjects:NSLinguisticTagSchemeLanguage, nil];
    NSLinguisticTagger *tagger = [[NSLinguisticTagger alloc] initWithTagSchemes:tagschemes options:0];
    [tagger setString:self];
    NSString *language = [tagger tagAtIndex:0 scheme:NSLinguisticTagSchemeLanguage tokenRange:NULL sentenceRange:NULL];
    if ([language rangeOfString:@"he"].location != NSNotFound || [language rangeOfString:@"ar"].location != NSNotFound) {
        return NSTextAlignmentRight;
    } else {
        return NSTextAlignmentLeft;
    }
}
@end

Чтобы определить язык, на котором я использовал этот ответ SO.

Ответ 3

@Aviel ответ как быстрое расширение UILabel

//MARK: UILabel extension
extension UILabel {
    func decideTextDirection () {
        let tagScheme = [NSLinguisticTagSchemeLanguage]
        let tagger    = NSLinguisticTagger(tagSchemes: tagScheme, options: 0)
        tagger.string = self.text
        let lang      = tagger.tagAtIndex(0, scheme: NSLinguisticTagSchemeLanguage,
            tokenRange: nil, sentenceRange: nil)

        if lang?.rangeOfString("he") != nil ||  lang?.rangeOfString("ar") != nil {
            self.textAlignment = NSTextAlignment.Right
        } else {
            self.textAlignment = NSTextAlignment.Left
        }
    }
}

Как его использовать?

label.text = "كتابة باللغة العربية" // Assign text
label.decideTextDirection()          // Decide direction

Ответ 4

Я думаю, вы не хотите использовать выравнивание текста в этом случае для ярлыка.

Вы можете просто определить ширину, определяемую intrinsicContentSize, и удалить любые ограничения ширины на метке. Вы достигнете желаемого эффекта текста меток, выровненного по отношению к представлению.

Для оси x вам нужно только это ограничение между меткой и изображением: [ImageView] - [метка]

Это ограничение только по горизонтали. Нет ведущего или завершающего просмотра.

Ответ 5

Следуйте за ответом Кена

Настройка textAlignment на NSTextAlignmentNatural невозможна на UILabel, это приведет к тому, что получится исключение:

Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: 'textAlignment does not accept NSTextAlignmentNatural'

Он работает при использовании атрибутного текста, и этот может быть установлен в Interface Builder, как показано ниже:

attributed text natural alignment

Однако, по-видимому, при локализации раскадровки приписанный текст не подбирается.

Чтобы обойти это, я оставил UILabel, настроенный как простой в Interface Builder, и создал текст NSAttributedString с текстом ярлыка, установил выравнивание в атрибутной строке и присвоил ей свойство label attributedText:

-(void)viewDidLoad
{
    [super viewDidLoad];

    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
    paragraphStyle.alignment = NSTextAlignmentNatural;

    NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:self.lbl.text];
    [string addAttribute:NSParagraphStyleAttributeName
                   value:paragraphStyle
                   range:NSMakeRange(0, string.length)];

    self.lbl.attributedText = string;
}

Это прекрасно работает в этом простом случае, но я вижу, что он падает, когда вам нужно более сложное приписываемое стилирование строк. Но, очевидно, в этом случае вы, вероятно, просто используете NSLocalizedString или эквиваленты при создании NSAttributedString.

Ответ 6

Эта функция помогла мне

-(void)fnForWritingDirection:(UILabel*)label textFor:(NSString *)stringForText{

    NSMutableAttributedString* attrStr = [[NSMutableAttributedString alloc] initWithString: [stringForText stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];

    [paragraphStyle setBaseWritingDirection:NSWritingDirectionRightToLeft];

    [attrStr addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [attrStr length])];

    label.attributedText=attrStr;

}

Ответ 7

Вы можете использовать MyLinearLayout для простой поддержки RTL и LRT.

Ответ 8

@Aviel ответ как быстрое расширение 4 UILabel

extension UILabel {
    func decideTextDirection () {
        let tagScheme = [NSLinguisticTagScheme.language]
        let tagger    = NSLinguisticTagger(tagSchemes: tagScheme, options: 0)
        tagger.string = self.text
        let lang      = tagger.tag(at: 0, scheme: NSLinguisticTagScheme.language,
                                          tokenRange: nil, sentenceRange: nil)

        if lang?.rawValue.range(of: "he") != nil ||  lang?.rawValue.range(of: "ar") != nil {
            self.textAlignment = NSTextAlignment.right
        } else {
            self.textAlignment = NSTextAlignment.left
        }
    }
}

usage

использования
label.text = "كتابة باللغة العربية" // Assign text
label.decideTextDirection()          // Decide direction