web-dev-qa-db-fra.com

Comment définir la direction localisée dans l'application? (RTL si l'utilisateur sélectionne arabe, LTR si langue sélectionnée est l'anglais)

Mon application doit prendre en charge les langues arabe (de droite à gauche) et anglaise (de gauche à droite), je dois définir l'interface utilisateur et en fonction de la langue de sélection de l'utilisateur de mon application.

Je vais implémenter l'interface utilisateur avec NSLayoutConstraint afin qu'il puisse la mettre à jour automatiquement, en fonction des contraintes de début et de fin.

Maintenant, ma question est: comment puis-je y parvenir? Comme la langue de mon appareil est l'anglais et que l'utilisateur de mon application sélectionne l'arabe (uniquement pour mon application), mon flux, mon interface utilisateur, mes animations, etc. doivent être placés de droite à gauche.

voici l'exemple d'échantillon pour ui Direction  enter image description here  enter image description here

Merci 

16
Kanjariya-IOS

En bout de ligne, vous pouvez changer la langue depuis l’application. Mais, un un travail supplémentaire est nécessaire. J'énumère de l'information sur les limites de chaque version d'iOS, puis fournit la solution. parce que tout en expliquant la solution, vous devez comprendre la raison derrière celle-ci.

Mise à jour (iOS 9+)

Clé de la solution: semanticContentAttribute

Certains disent que cette façon de faire n'est pas officielle et peut causer des problèmes d'efficacité.

La direction de l'interface utilisateur peut être forcée maintenant sans fermer l'application:

UIView.appearance().semanticContentAttribute = .forceRightToLeft

Notez que les barres dans iOS 9 ne peuvent pas être forcées à RTL (Navigation et TabBar). Bien qu'il soit forcé avec iOS 10.

La dernière chose qui ne peut pas être forcée dans RTL dans iOS 10 est le bouton Précédent par défaut.

Changer la langue de l'application avec forcer la mise en page ne le fait pas oblige automatiquement le système à utiliser le fichier de chaîne localisé associé à la langue.

Sous iOS 9

Réponse courte:

Changer la langue de l'application ne force pas la direction de la mise en page en fonction de la langue sélectionnée sans redémarrage de l'application.

Guide de Apple:

Apple ne fournit pas cela parce qu'ils ne préfèrent pas autoriser l'utilisateur pour changer la langue de l'intérieur de l'application. Apple pousse les développeurs à utiliser la langue de l'appareil. et ne pas le changer de l'intérieur de l'application du tout.

Workarwound:

Certaines applications qui prennent en charge la langue arabe note l'utilisateur, dans le page de paramètres où l'utilisateur peut changer de langue, que la mise en page ne prendra pas en compte sans un redémarrage de l'application. le magasin lien pour exemple d'application

Exemple de code pour changer la langue de l'application en arabe:

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

Cela ne prendra pas effet sans redémarrage


Comment changer la langue de l'application sans redémarrer l'application

La solution consiste à fournir votre propre solution de localisation:

  1. Utilisez l’internationalisation de base mais ne localisez pas les storyboards.
  2. Créer un fichier de chaînes et le localiser dans toutes les langues et la base pour (anglais).
  3. Placez la fonctionnalité de changement de langue dans une ViewController qui commence avant toute autre ViewController même avant votre principale. OU utilise une unwindSegue pour revenir au contrôleur de vue racine après avoir changé de langue.
  4. Définissez les chaînes pour vos vues dans la méthode viewDidLoad pour tous les contrôleurs de vue.

Ne répondez pas aux points 5 et 6 si vous ne supportez pas iOS 9

  1. Définissez les contraintes pour vos vues dans la méthode viewDidLoad pour tous les contrôleurs de vue.

  2. Lorsque vous définissez les contraintes, utilisez right/left en fonction de la langue sélectionnée au lieu de lead/fin.


Exemple de classe de langue (Swift): Initialisez un objet de cette classe dans votre classe singlton.

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: "")
    }
}

Exemple de classe de langue (Objective-c): Un échantillon de Swift fournit une solution complète. désolé vous avez besoin de le convertir vous-même.

@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

utilisez Marges de disposition directionnelle (iOS 11.0+)

 enter image description here

et définissez Vues sur

De droite à gauche

 UIView.appearance().semanticContentAttribute = .forceRightToLeft

De gauche à droite

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