AutoLayout + RTL + UILabel text alignment

前端 未结 9 1032
面向向阳花
面向向阳花 2020-11-28 11:18

I\'m finally getting round to wrestling with Auto Layout and can\'t seem to figure out how to get right-to-left (RTL) support to work the way I\'d expect/want...

I h

相关标签:
9条回答
  • 2020-11-28 11:35

    @Aviel answer as a swift 4 UILabel extension

    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
    
    0 讨论(0)
  • 2020-11-28 11:35

    Here is my version. It's simpler and also handles multiple languages in the source document.

    The Main point is to use the dominantLanguage:

    let lang = tagger.dominantLanguage
    

    Code Snippet:

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

    Usage:

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

    Finally: Note that if the App is localized and you may rely on the phones language - the solution your after is: "Natural Text Alignment for RTL": i.e:

    titleLabel.textAlignment = .natural
    

    Use the NSLinguisticTagger when your app shows multiple lines with different languages. or when you allow free search in any language, regardless of the local.

    0 讨论(0)
  • 2020-11-28 11:36

    You want NSTextAlignmentNatural. That infers the text alignment from the loaded application language (not from the script).

    For iOS 9 and later (using Xcode 7), you can set this in the storyboard (choose the --- alignment option). If you need to target earlier releases, you'll need to create an outlet to the label and set the alignment in awakeFromNib.

    - (void)awakeFromNib {
        [[self label] setTextAlignment:NSTextAlignmentNatural];
    }
    
    0 讨论(0)
  • 2020-11-28 11:45

    You can use MyLinearLayout to easy support RTL and LRT.

    0 讨论(0)
  • 2020-11-28 11:46

    For me those solutions didn't help, and I ended up doing something pretty ugly but it's the only one that did the trick for me. I added it as an NSString category:

    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
    

    To detect the language I used this SO answer.

    0 讨论(0)
  • 2020-11-28 11:48

    @Aviel answer as a swift UILabel extension

    //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
            }
        }
    }
    

    How to use it ?

    label.text = "كتابة باللغة العربية" // Assign text
    label.decideTextDirection()          // Decide direction
    
    0 讨论(0)
提交回复
热议问题