27

我终于开始与自动布局搏斗,似乎无法弄清楚如何获得从右到左(RTL)的支持以按照我期望/想要的方式工作......

我在 Interface Builder 中设计了视图,如下所示:

国际文凭组织

使用英语时生成的应用程序按预期运行:

英语

但是,当切换到 RTL 语言(在这种情况下为阿拉伯语)时,整个视图会翻转(这很棒),但UILabel's 的文本仍然是左对齐的。我希望它能够正确对齐以使其与UIImageView.

阿拉伯

显然我遗漏了一些东西和/或这不在自动布局中。

textAlignment使用 RTL 语言时是否应该手动设置?

4

10 回答 10

32

你想要NSTextAlignmentNatural这从加载的应用程序语言(而不是脚本)推断出文本对齐方式。

对于 iOS 9 及更高版本(使用 Xcode 7),您可以在情节提要中进行设置(选择 --- 对齐选项)。如果您需要针对较早的版本,您需要为标签创建一个出口并在awakeFromNib.

- (void)awakeFromNib {
    [[self label] setTextAlignment:NSTextAlignmentNatural];
}
于 2013-09-11T18:37:23.373 回答
13

对我来说,这些解决方案没有帮助,我最终做了一些非常丑陋的事情,但它是唯一对我有用的解决方案。我将其添加为一个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 answer的语言。

于 2014-04-10T12:28:42.240 回答
5

跟进肯的回答

无法设置textAlignment为,这将导致抛出异常:NSTextAlignmentNaturalUILabel

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

它在使用属性文本时确实有效,可以在 Interface Builder 中设置,如下所示:

属性文本自然对齐

但是,在本地化情节提要时,似乎没有拾取属性文本。

为了解决这个问题,我UILabel在 Interface Builder 中将配置保留为纯NSAttributedString文本,并使用标签的文本创建了一个,在属性字符串上设置对齐并将其分配给标签的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.

于 2013-09-12T08:32:24.480 回答
5

@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
于 2016-02-08T11:55:16.380 回答
4

我认为您不想在这种情况下对标签使用文本对齐方式。

您可以让宽度由intrinsicContentSize 确定,并删除标签上的任何宽度限制。您将获得与视图对齐的标签文本的预期效果。

对于 x 轴,你只需要 label 和 imageview 之间的这个约束:[imageview]-[label]

这只是一个水平间距约束。没有领先或落后于 superview。

于 2013-09-11T16:19:08.060 回答
3

@Aviel 作为 swift 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
        }
    }
}

用法

label.text = "كتابة باللغة العربية" // Assign text
label.decideTextDirection()          // Decide direction
于 2018-11-04T09:06:56.727 回答
1

这个功能帮了我

-(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;

}
于 2015-05-07T08:32:10.243 回答
1

这对我有用:

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)
        let langDir = NSLocale.characterDirection(forLanguage: lang?.rawValue ?? "en")
        if langDir == .rightToLeft { self.textAlignment = NSTextAlignment.right }
        else { self.textAlignment = NSTextAlignment.left }
    }
}

用法:

nameLabel.text = "مهدی"
nameLabel.decideTextDirection()
于 2021-12-25T01:08:02.743 回答
0

您可以使用MyLinearLayout轻松支持 RTL 和 LRT。

于 2017-05-16T03:02:51.527 回答
0

这是我的版本。它更简单,还可以处理源文档中的多种语言。

要点是使用dominantLanguage:

let lang = tagger.dominantLanguage

代码片段:

 extension UILabel {
    func determineTextDirection () {
        guard self.text != nil else {return}

        let tagger = NSLinguisticTagger(tagSchemes: [.language], options: 0)
        tagger.string = self.text

        let lang = tagger.dominantLanguage

        let rtl = lang == "he" || lang == "ar"

        self.textAlignment = rtl ? .right : .left
    }
}

用法:

titleLabel.text = "UILabel היפוך שפה עבור"
titleLabel.determineTextDirection()

最后:请注意,如果应用程序已本地化并且您可能依赖手机语言 - 您之后的解决方案是:“RTL 的自然文本对齐”:即:

titleLabel.textAlignment = .natural

在此处输入图像描述

当您的应用程序显示多行不同语言时,请使用 NSLinguisticTagger。或者当您允许以任何语言免费搜索时,无论本地语言如何。

于 2020-02-13T15:16:54.580 回答