AutoLayout + RTL + UILabel文本alignment

我终于轮到与自动布局摔跤,似乎无法弄清楚如何从右到左(RTL)的支持工作,我希望/希望的方式…

我在界面生成器中devise了如下所示的视图:

IB

如果使用英语,结果应用程序按预期运行:

英语

但是,当切换到RTL语言(在这种情况下,阿拉伯语),整个视图翻转(这是伟大的),但UILabel的文本仍左alignment。 我希望它是正确的alignment,以保持它对UIImageView

阿拉伯

很明显,我错过了一些东西,或者这不在自动布局中。

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

你想要NSTextAlignmentNatural 。 这推断来自加载的应用程序语言( 不是来自脚本)的文本alignment。

对于iOS 9和更高版本(使用Xcode 7),可以在故事板中设置它(select—alignment选项)。 如果您需要定位较早版本,则需要创build标签的出口,并在awakeFromNib设置alignment方式。

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

对我来说,那些解决scheme并没有帮助,而且我做了一件相当丑陋的事情,但这是唯一一个对我有用的技巧。 我将它添加为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回答的语言。

在这种情况下,我认为你不希望使用文本alignment。

您可以让宽度由intrinsicContentSize确定,并删除标签上的任何宽度约束。 您将实现与视图alignment的标签文本所需的效果。

对于x轴,您只需要在标签和图像视图之间使用此约束:[imageview] – [label]

这只是一个水平间距约束。 没有领先或追踪超级查看。

从肯的回答跟进

UILabel上设置textAlignmentNSTextAlignmentNatural是不可能的,这会导致抛出一个exception:

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

它在使用属性文本时可以工作 ,并且可以在Interface Builder中设置,如下所示:

归因文本自然对齐

但是,在定位故事板时,看起来属性文本不会被拾取。

为了解决这个问题,我在界面生成器中将UILabelconfiguration为普通的,并用标签的文本创build了一个NSAttributedString ,在属性string上设置alignment方式,并将其分配给标签的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; } 

这在这个简单的例子中工作正常,但是当你需要更复杂的属性string样式时,我可以看到它摔倒。 但显然在这种情况下,你可能只是在创buildNSAttributedString时使用NSLocalizedString或等价物。

@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 

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

这个function帮了我

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