web-dev-qa-db-fra.com

iOS: déterminer si la langue de l'appareil est de droite à gauche (RTL)

Existe-t-il un moyen de déterminer facilement si la langue sur laquelle l'appareil est défini est de droite à gauche (RTL)?

46
BarrettJ

Dans iOS 9, on peut déterminer la direction actuelle de chaque vue individuelle.

if #available(iOS 9.0, *) {
  if UIView.userInterfaceLayoutDirection(
    for: myView.semanticContentAttribute) == .rightToLeft {

      // The view is shown in right-to-left mode right now.
  }
} else {
    // Use the previous technique
    if UIApplication.shared.userInterfaceLayoutDirection == .rightToLeft {

        // The app is in right-to-left mode
    }
}

Il s'agit de la méthode recommandée pour déterminer la direction de la mise en page dans iOS 9.

Vidéo WWDC 2015 Nouveau support UIKit pour les interfaces utilisateurs internationales . Après la minute 31:20.

56
Evgenii

Il existe une manière officielle de procéder:

if ([UIApplication sharedApplication].userInterfaceLayoutDirection == UIUserInterfaceLayoutDirectionRightToLeft) {
}

Je déconseille d'utiliser certaines des autres solutions, car elles ne renverront pas toujours les paramètres régionaux corrects. Ce n'est pas parce qu'il est au-dessus des langues préférées que l'application le prend en charge.

Source: https://developer.Apple.com/library/content/documentation/MacOSX/Conceptual/BPInternational/SupportingRight-To-LeftLanguages/SupportingRight-To-LeftLanguages.html

40
Accatyyc

NSLocale a deux méthodes +characterDirectionForLanguage: et +lineDirectionForLanguage:. Le premier est vraisemblablement de gauche à droite vs de droite à gauche et le second est de haut en bas vs de bas en haut. Vous pouvez lui transmettre le résultat de [[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode].

Mise à jour:

La question initiale posée était de savoir comment déterminer si la langue de l'appareil est RTL. En utilisant +[NSLocale characterDirectionForLanguage:] et +[NSLocale lineDirectionForLanguage:] est sans ambiguïté correct pour cela; vous pouvez passer soit [[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode] ou [NSLocale preferredLanguages][0] à cela pour obtenir les informations pertinentes (je ne suis pas sûr si le NSLocaleLanguageCode utilise la langue préférée ou la région définie).

Cependant, il est très probable que ce que l'affiche originale voulait réellement savoir, c'est si l'interface de l'application doit être présentée en RTL ou LTR. C'est très similaire à demander quelle est la direction de la langue, sauf qu'elle prend en compte les localisations disponibles de l'application. Si l'application n'est pas localisée dans la langue préférée de l'utilisateur, elle utilisera à la place une langue non préférée. Et la réponse à cette question est d'utiliser [UIApplication sharedApplication].userInterfaceLayoutDirection.

17
Lily Ballard

Assurez-vous de renvoyer la langue actuellement sélectionnée, pas la région actuelle de l'appareil. La région et la langue sont souvent les mêmes. Cependant, si je suis en Amérique du Nord et que je mets ma langue au japonais, ma région sera toujours l'anglais (États-Unis). Afin de vérifier la direction des caractères de la langue actuellement sélectionnée, vous pouvez faire:

+ (BOOL)isDeviceLanguageRTL {
  return ([NSLocale characterDirectionForLanguage:[[NSLocale preferredLanguages] objectAtIndex:0]] == NSLocaleLanguageDirectionRightToLeft);
}

Vous souhaiterez probablement mettre le résultat en cache en utilisant dispatch_once.

N'oubliez pas qu'il s'agit de la direction linguistique préférée de l'utilisateur, et pas nécessairement de la direction linguistique du texte. Pour cela, utilisez une fonction C basée sur u_charDirection.

10
Rose Perrone

Voici une version Swift 3:

import UIKit

extension UIView
{
    /// Returns text and UI direction based on current view settings
    var userInterfaceLayoutDirection: UIUserInterfaceLayoutDirection
    {
        if #available(iOS 9.0, *) {
            return UIView.userInterfaceLayoutDirection(for: self.semanticContentAttribute)
        } else {
            return UIApplication.shared.userInterfaceLayoutDirection
        }
    }
}
5
David Rysanek

Grâce à la réponse de Kevin Ballard, j'ai pu créer la fonction utilitaire suivante pour ce faire:

+ (BOOL)isDeviceLanguageRTL {
   return [NSLocale characterDirectionForLanguage:[[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]]==NSLocaleLanguageDirectionRightToLeft;
}
4
Gerhat

Ok, bien que ce soit une vieille question avec une réponse acceptée, je vais y répondre quand même.

Pour ceux qui veulent vérifier si la langue de l'appareil est RTL, indépendant si votre application prend en charge ou non cette langue, vous devez utiliser [NSLocale characterDirectionForLanguage:] comme ça:

+ (BOOL)isDeviceLanguageRightToLeft {

    NSLocale *currentLocale = [NSLocale currentLocale];
    NSLocaleLanguageDirection direction = [NSLocale characterDirectionForLanguage:[currentLocale objectForKey:NSLocaleLanguageCode]];
    return (direction == NSLocaleLanguageDirectionRightToLeft);
}

Le code ci-dessus renverra YES si votre application ne prend en charge que l'anglais, mais que votre appareil est défini sur l'arabe par exemple.

Apple vous recommande d'utiliser [UIApplication sharedApplication].userInterfaceLayoutDirection, simplement parce qu'il renvoie la direction en fonction de la langue que votre application utilise (prend en charge). Voici l'extrait de code:

+ (BOOL)isAppLanguageRightToLeft {

    NSLocaleLanguageDirection direction = [UIApplication sharedApplication].userInterfaceLayoutDirection;
    return (direction == UIUserInterfaceLayoutDirectionRightToLeft);
}

Le code ci-dessus renverra NO lorsque votre application ne prend en charge que l'anglais, mais que votre appareil est défini sur l'arabe par exemple.

1
FormigaNinja

si vous voulez vérifier si l'appareil fonctionne en RTL ou LTR en Swift 3

if(UIApplication.shared.userInterfaceLayoutDirection == UIUserInterfaceLayoutDirection.rightToLeft) {
    //RTL
} else {
   //LTR
}
1
Tarek hemdan
if ([[UIDevice currentDevice].systemVersion floatValue] >= 9.0) {
    if ([UIView userInterfaceLayoutDirectionForSemanticContentAttribute:self.view.semanticContentAttribute] == UIUserInterfaceLayoutDirectionRightToLeft) {
        NSLog(@"Right to left");
    }
    else{
        NSLog(@"left to Right");
    }
} else {
    /* Use the previous technique */
    //Work for earlier ios 6 to ios 10
    if ([NSLocale characterDirectionForLanguage:[[NSLocale preferredLanguages] objectAtIndex:0]] == NSLocaleLanguageDirectionRightToLeft) {
        NSLog(@"Right to left");
    }
    else{
        NSLog(@"left to Right");
    }
}

doit regarder Sujets avancés en internationalisation wwdc2014

1
Ravi Kumar

Voici comment je l'ai utilisé:

+(NSTextAlignment) alignmentOfLanguage {
if ([NSLocale characterDirectionForLanguage:[[NSLocale preferredLanguages] objectAtIndex:0]]==NSLocaleLanguageDirectionRightToLeft){
        return NSTextAlignmentRight;
    }
   return NSTextAlignmentLeft;  
}

Le dernier exemple n'a pas fonctionné pour moi, mais avec une petite variante, je l'ai bien compris X2.

des commentaires?

1
Y.Z.

Rose Perrone a parfaitement raison. Cependant, l'utilisation de dispatch_once dans un getter pour une valeur booléenne simple est vraiment trop lourde. Utilisation inutile de l'envoi une fois. Parce que vous voudrez probablement l'utiliser autant de fois dans une fonction de mise en page ou de dessin.

Vous avez donc deux options plus rapides:

+ (BOOL)isRtl
{
    static BOOL isRtl = NO;
    static BOOL isRtlFound = NO;
    if (!isRtlFound)
    { // This is "safe enough". Worst case is this code will be called twice in the app's lifecycle...
        isRtl = [NSLocale characterDirectionForLanguage:[NSBundle mainBundle].preferredLocalizations[0]] == NSLocaleLanguageDirectionRightToLeft;
        isRtlFound = YES;
    }
    return isRtl;
}

Ou mettez-le simplement en cache dans une variable statique, en utilisant le constructeur statique:

static BOOL s_isRtl = NO;
+ initialize
{
    s_isRtl = [NSLocale characterDirectionForLanguage:[NSBundle mainBundle].preferredLocalizations[0]] == NSLocaleLanguageDirectionRightToLeft;
}

Notez que cela partagera en fait la variable statique entre toutes les classes qui utilisent ce code.

0
daniel.gindi