it-swarm.com.de

Wie kann ich die lokalisierte Richtung in der Anwendung festlegen?

Meine Anwendung muss die arabische Sprache (von rechts nach links) und die englische Sprache (von links nach rechts) unterstützen. Ich muss die Benutzeroberfläche einstellen und die Benutzeroberfläche auf der Grundlage der vom Benutzer ausgewählten Sprache auswählen.

Ich werde die Benutzeroberfläche mit NSLayoutConstraint implementieren, damit die Benutzeroberfläche automatisch aktualisiert werden kann, basierend auf führenden und nachgestellten Einschränkungen.

Jetzt ist meine Frage, wie kann ich das erreichen? Da meine Gerätesprache Englisch ist, wählen Sie aus meinem Anwendungsbenutzer Arabisch aus (beschränkt auf meine App). Daher sollten mein Flow, meine Benutzeroberfläche, Animationen usw. von rechts nach links sein.

hier ist der Beispiel-Snap für Ui Direction  enter image description here  enter image description here

Vielen Dank 

16
Kanjariya-IOS

Unterm Strich können Sie die Sprache innerhalb der App ändern. Aber ein zusätzliche arbeit ist erforderlich. Ich führe einen Hintergrund zu den Einschränkungen für jede iOS-Version an und biete dann die Lösung an. denn während Sie die Lösung erklären, müssen Sie den Grund dafür verstehen.

Update (iOS 9+)

Lösungsschlüssel: semanticContentAttribute

Einige sagen, dass dieser Weg nicht offiziell ist und Effizienzprobleme verursachen kann.

Die Benutzeroberflächenrichtung kann jetzt erzwungen werden, ohne die App zu schließen:

UIView.appearance().semanticContentAttribute = .forceRightToLeft

Beachten Sie, dass Balken in iOS 9 nicht in RTL (Navigation und TabBar) umgewandelt werden können. Während es mit iOS 10 gezwungen wird.

Die einzige verbleibende Sache, die RTL in iOS 10 nicht erzwungen werden kann, ist die Standard-Zurück-Schaltfläche.

Wenn Sie die Sprache der App zusammen mit dem Erzwingen des Layouts ändern, wird dies nicht zwingt das System automatisch zur Verwendung der lokalisierten String-Datei mit der Sprache verbunden.

Unter iOS 9

Kurze Antwort:

Wenn Sie die App-Sprache ändern, wird die Layoutrichtung der ausgewählten Sprache nicht ohne einen Neustart der App erzwungen.

Apples Leitlinie:

Apple bietet das nicht an, weil sie es nicht vorziehen, den Benutzer .__ zuzulassen. um die Sprache aus der App heraus zu ändern. Apple drängt die Entwickler auf Verwenden Sie die Gerätesprache. und es nicht aus der App zu ändern.

Workarwound:

Einige Apps, die die arabische Sprache unterstützen, notieren den Benutzer in der Einstellungsseite, auf der der Benutzer die Sprache ändern kann, so dass das Layout nicht ohne einen Neustart der App wirksam wird. Geschäft Link zur Beispiel-App

Beispielcode zum Ändern der App-Sprache in Arabisch:

[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:@"ar", @"en", nil] forKey:@"AppleLanguages"];

Das wird ohne Neustart nicht wirksam


So ändern Sie die App-Sprache ohne Neustart der App

Die Lösung besteht darin, eine eigene Lokalisierungslösung bereitzustellen:

  1. Base Internationalization verwenden, Storyboards nicht lokalisieren.
  2. Erstellen Sie eine String-Datei und lokalisieren Sie sie in alle Sprachen und Basis für (Englisch).
  3. Platzieren Sie die Funktion zum Ändern der Sprache in einer ViewController, die vor jeder anderen ViewController beginnt, sogar vor Ihrer Hauptvariable. ODER verwenden eine unwindSegue, um nach dem Ändern der Sprache zum Root-View-Controller zurückzukehren.
  4. Legen Sie in viewDidLoad für alle Ansichtscontroller Zeichenfolgen für Ihre Ansichten fest.

Erfüllen Sie die Punkte 5 und 6 nicht, wenn Sie nicht unter iOS 9 unterstützen.

  1. Legen Sie die Einschränkungen für Ihre Ansichten in der viewDidLoad-Methode für alle Ansichtscontroller fest.

  2. Wenn Sie die Bedingungen festlegen, verwenden Sie right/left entsprechend der ausgewählten Sprache anstelle von Führen/Nachlaufen.


Sprachklassenbeispiel (Swift): Initialisieren Sie ein Objekt dieser Klasse in Ihrer Einzelklasse.

class LanguageDetails: NSObject {

    var language: String!
    var bundle: Bundle!
    let LANGUAGE_KEY: String = "LANGUAGE_KEY"

    override init() {
        super.init()

        // user preferred languages. this is the default app language(device language - first launch app language)!
        language = Bundle.main.preferredLocalizations[0]

        // the language stored in UserDefaults have the priority over the device language.
        language = Common.valueForKey(key: LANGUAGE_KEY, default_value: language as AnyObject) as! String

        // init the bundle object that contains the localization files based on language
        bundle = Bundle(path: Bundle.main.path(forResource: language == "ar" ? language : "Base", ofType: "lproj")!)

        // bars direction
        if isArabic() {
            UIView.appearance().semanticContentAttribute = .forceRightToLeft
        } else {
            UIView.appearance().semanticContentAttribute = .forceLeftToRight
        }
    }

    // check if current language is arabic
    func isArabic () -> Bool {
        return language == "ar"
    }

    // returns app language direction.
    func rtl () -> Bool {
        return Locale.characterDirection(forLanguage: language) == Locale.LanguageDirection.rightToLeft
    }

    // switches language. if its ar change it to en and vise-versa
    func changeLanguage()
    {
        var changeTo: String
        // check current language to switch to the other.
        if language == "ar" {
            changeTo = "en"
        } else {
            changeTo = "ar"
        }

        // change language
        changeLanguageTo(lang: changeTo)

        Log.info("Language changed to: \(language)")
    }

    // change language to a specfic one.
    func changeLanguageTo(lang: String) {
        language = lang

        // set language to user defaults
        Common.setValue(value: language as AnyObject, key: LANGUAGE_KEY)

        // set prefered languages for the app.
        UserDefaults.standard.set([lang], forKey: "AppleLanguages")
        UserDefaults.standard.synchronize()

        // re-set the bundle object based on the new langauge
        bundle = Bundle(path: Bundle.main.path(forResource: language == "ar" ? language : "Base", ofType: "lproj")!)

        // app direction
        if isArabic() {
            UIView.appearance().semanticContentAttribute = .forceRightToLeft
        } else {
            UIView.appearance().semanticContentAttribute = .forceLeftToRight
        }

        Log.info("Language changed to: \(language)")
    }

    // get local string
    func getLocale() -> NSLocale {
        if rtl() {
            return NSLocale(localeIdentifier: "ar_JO")
        } else {
            return NSLocale(localeIdentifier: "en_US")
        }
    }

    // get localized string based on app langauge.
    func LocalString(key: String) -> String {
        let localizedString: String? = NSLocalizedString(key, bundle: bundle, value: key, comment: "")
//        Log.ver("Localized string '\(localizedString ?? "not found")' for key '\(key)'")
        return localizedString ?? key
    }

    // get localized string for specific language
    func LocalString(key: String, lan: String) -> String {
        let bundl:Bundle! = Bundle(path: Bundle.main.path(forResource: lan == "ar" ? lan : "Base", ofType: "lproj")!)
        return NSLocalizedString(key, bundle: bundl, value: key, comment: "")
    }
}

Sprachklassenbeispiel (Objective-c): Swift-Beispiel bietet vollständige Lösung. Entschuldigung, Sie müssen es selbst konvertieren.

@implementation LanguageDetails

@synthesize language;
@synthesize bundle;

#define LANGUAGE_KEY @"LANGUAGE_KEY"

// language var is also the strings file name ar or en

- (id)init
{
    if (self = [super init]) {

        language = [[[NSBundle mainBundle] preferredLocalizations] objectAtIndex:0];

        if (![language isEqualToString:@"ar"])
            language = @"en";

        language = [Common valueForKey:LANGUAGE_KEY defaultValue:language];

        bundle = [NSBundle mainBundle];
    }
    return  self;
}

- (BOOL)rtl {
    return [NSLocale characterDirectionForLanguage:language] == NSLocaleLanguageDirectionRightToLeft;
}

- (void)changeLanguage
{
    if ([language isEqualToString:@"ar"])
        language = @"en";
    else
        language = @"ar";

    [Common setValue:language forKey:LANGUAGE_KEY];
}

- (void)changeLanguageTo:(NSString *)lang
{
    language = lang;

    [Common setValue:language forKey:LANGUAGE_KEY];
}

- (NSString *) LocalString:(NSString *)key {
    return NSLocalizedStringFromTableInBundle(key, language, bundle, nil);
}

@end
30
hasan

Verwenden Sie diese Codezeile, um Ihre Magie zu entfalten und das Layout zu ändern, ohne die Anwendung zu schließen. Von rechts nach links

UIView.appearance().semanticContentAttribute = .forceRightToLeft

Und für rechts nach links Flip

UIView.appearance().semanticContentAttribute = .forceLeftToRight

und wenn Sie das Textfeldlayout oder die Textänderung ändern möchten, verwenden Sie diesen Code, da ich mit diesem Problem konfrontiert war. Die Texte von textfield änderten nicht das Layout. Aktivieren Sie diesen Code, um das Layout des Textfeldtextes zu ändern.

extension UITextField {
  open override func awakeFromNib() {
    super.awakeFromNib()
    if UserDefaults.languageCode == "ar" {
        if textAlignment == .natural {
            self.textAlignment = .right
        }
    }
}
}
2

@ashwin, ich habe versucht, genau dasselbe zu tun wie Sie.

Ich hatte gehofft, dass ich meine App in eine RTL-Sprache (von rechts nach links) umwandeln kann, indem ich einfach etwas in der info.plist, appdelegate oder wer weiß was ändere. Die Idee ist, dass jemand mit einem LTR-Gerät meine App in RTL haben kann, sie innerhalb der App ändert und sie nicht neu starten muss.

Sieht so aus, als gäbe es so etwas nicht (ich bin froh zu hören, wenn jemand damit nicht einverstanden ist). Ich habe jedoch einige Optionen gefunden, die nicht so schlecht sind.

  1. Es stellt sich heraus, dass Sie eine bestimmte Ansicht als LTR oder RTL erzwingen können. So können Sie diese Eigenschaft in jeder Ansicht Ihrer App einstellen. Wie Sie es tun, liegt an Ihnen.

    self.view.semanticContentAttribute = UISemanticContentAttributeForceRightToLeft;

Referenz: ISemanticContentAttribute

  1. Sie können Ansichten immer horizontal spiegeln, bis Sie das gewünschte Setup erhalten.

[view setTransform:CGAffineTransformMakeScale(1, 1)];

Hier ist ein Code, der Ihnen helfen könnte.

void reloadRTLViewAndSubviews(UIView *view)
{
    reloadRTLViews(@[view]);
    reloadRTLViews([view subviews]);
}

void reloadRTLViews(NSArray *views)
{
    if (isRTL())
    {
        [views enumerateObjectsUsingBlock:^(UIView* view,
                                            NSUInteger idx,
                                            BOOL * stop)
         {
             [view setTransform:CGAffineTransformMakeScale(-1, 1)];
         }];
    }
    else
    {
        [views enumerateObjectsUsingBlock:^(UIView* view,
                                            NSUInteger idx,
                                            BOOL * stop)
         {
             [view setTransform:CGAffineTransformMakeScale(1, 1)];
         }];
    }
}

BOOL isRTL()
{
    return isRTL_app();
}

BOOL isRTL_device()
{
    BOOL isRTL = ([NSLocale characterDirectionForLanguage:[[NSLocale preferredLanguages] objectAtIndex:0]] == NSLocaleLanguageDirectionRightToLeft);

    return isRTL;
}

BOOL isRTL_scheme()
{
    BOOL isRTL = ([UIView userInterfaceLayoutDirectionForSemanticContentAttribute:[UIView new].semanticContentAttribute] == UIUserInterfaceLayoutDirectionRightToLeft);

    return isRTL;
}

BOOL isRTL_app()
{
    NSString *languageIdentifier = [AppDataManager sharedManager].languageIdentifier;
    NSArray *rtl_languages = @[@"ar"];

    BOOL isRTL;

    if ((languageIdentifier == nil) || (languageIdentifier.length == 0))
    {
        isRTL = (isRTL_device() || isRTL_scheme());
    }
    else if ([rtl_languages containsObject:languageIdentifier])
    {
        isRTL = YES;
    }
    else
    {
        isRTL = NO;
    }

    return isRTL;
}

BOOL deviceLanguageDirectionEqualAppLanguageDirection()
{
    if ((isRTL_device() || isRTL_scheme()) && isRTL())//All RTL
    {
        return YES;
    }
    else if (!(isRTL_device() || isRTL_scheme()) && !isRTL())//All LTR
    {
        return YES;
    }

    return NO;//RTL-LTR or LTR-RTL
}

void transformViews(NSArray *views)
{
    [views enumerateObjectsUsingBlock:^(UIView* view,
                                        NSUInteger idx,
                                        BOOL * stop)
     {
         [view setTransform:CGAffineTransformMakeScale(-1, 1)];
     }];
}

Wenn Sie also einen UIViewController in RTL ändern, können Sie das gesamte Setup so vornehmen, dass es ausreicht, um:

reloadRTLViewAndSubviews(self.view);

Hinweis: Dies sollte nicht der Fall sein, und nach den Richtlinien von Apple sollte die Sprache in den iOS-Einstellungen geändert werden. Diese Lösung funktioniert jedoch, wenn die Sprache in der App geändert werden muss und ein Richtungswechsel zwischen LTR und RTL erforderlich ist. Auch ein App-Reset ist nicht erforderlich.

Ich hoffe es hat geholfen.

1
inigo333

verwenden Sie Directional Layout Margins (iOS 11.0+)

 enter image description here

und setze Ansichten auf

Rechts nach links

 UIView.appearance().semanticContentAttribute = .forceRightToLeft

Links nach rechts

 UIView.appearance().semanticContentAttribute = .forceLeftToRight
0
MAhipal Singh