Question Activation de la mise en page automatique dans iOS 6 tout en restant compatible avec iOS 5


Quelle est la meilleure façon de tirer parti des nouvelles fonctionnalités de mise en page automatique d'iOS 6 tout en assurant la compatibilité avec les appareils plus anciens sur les versions antérieures d'iOS?


151
2017-09-13 17:50


origine


Réponses:


Autolayout peut être activé ou désactivé sur chaque fichier .storyboard ou .xib. Sélectionnez simplement le fichier particulier et modifiez la propriété "Use Autolayout" en utilisant l'inspecteur de fichiers dans Xcode:

autolayout property in the File inspector

L'utilisation des fichiers d'interface avec l'autolayout avec la cible de déploiement définie sur une version iOS antérieure à 6.0 entraîne des erreurs de compilation, par exemple:

Erreur dans MainStoryboard.storyboard: 3: Mise en page automatique sur les versions iOS antérieures à 6.0

Une de vos options pour utiliser autolayout dans un projet et préserver la compatibilité avec iOS4-5 est de créer deux des cibles: un pour la cible de déploiement iOS 6.0 et un pour une version antérieure d’iOS, par exemple:

enter image description here

Vous pouvez également créer deux versions pour chacun de vos fichiers storyboard et XIB et utiliser l'autolayout activé avec la cible 6.0 et l'autre avec la cible héritée, par exemple:

enter image description here

Vous ajoutez ensuite MainStoryBoardAutoSize aux phases de génération de la cible iOS6 et l'autre fichier à la cible iOS4. Vous pouvez en apprendre plus sur l'utilisation de plusieurs cibles ici.

EDIT: comme La réponse de marchinram fait remarquer que si vous chargez des fichiers de storyboard à partir de code et que vous n'utilisez pas le paramètre "Storyboard principal" dans Xcode pour définir le storyboard initial, vous pouvez utiliser une seule cible.

Pour moi, le coût de la complexité supplémentaire liée à la maintenance de plusieurs cibles et fichiers d’interface semble dépasser les avantages de l’utilisation d’autolayout. À l'exception de quelques cas particuliers, il est probablement préférable d'utiliser d'anciens dimensionnements automatiques (ou layoutSubViews à partir du code) uniquement si une compatibilité iOS4-5 est requise.


120
2017-09-21 20:20



Avez-vous vraiment besoin de deux cibles? Je l'ai fait fonctionner comme ça, j'ai 2 storyboards comme Imre Kelényi dit, l'un avec les mises en page automatiques activées et l'autre sans, alors dans l'application délégué je vérifie juste quelle version ils utilisent et sélectionne le bon storyboard:

#import "AppDelegate.h"

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:(v) options:NSNumericSearch] != NSOrderedAscending)

@interface AppDelegate ()
    @property (strong, nonatomic) UIViewController *initialViewController;
@end

@implementation AppDelegate

@synthesize window = _window;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    UIStoryboard *mainStoryboard = nil;
    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.0")) {
        mainStoryboard = [UIStoryboard storyboardWithName:@"iPhone_iOS6" bundle:nil];
    } else {
        mainStoryboard = [UIStoryboard storyboardWithName:@"iPhone_iOS5" bundle:nil];
    }

    self.initialViewController = [mainStoryboard instantiateInitialViewController];
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.rootViewController = self.initialViewController;
    [self.window makeKeyAndVisible];

    return YES;
}

@end

Avoir 2 cibles fonctionne aussi, mais cela me semble excessif


47
2017-09-25 23:40



Si les différences de disposition ne sont pas grandes, il est beaucoup plus facile à utiliser Ressorts et jambes pour positionner des éléments.


4
2017-10-04 18:04



Inspiré par l’idée unique de @marchinram, c’est la solution que j’ai finalement trouvée. Deux storyboards, un pour les jambes de force et un pour autolayout. Dans le résumé de la cible, je définis le storyboard autolayout par défaut. Ensuite, dans appDelegate, je vérifie si je dois charger le storyboard pré-6.0 struts-and-springs après tout:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    Class cls = NSClassFromString (@"NSLayoutConstraint");
    if (cls == nil) {
        NSString *mainStoryboardName = nil;
        if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
            mainStoryboardName = @"MainStoryboard_iPad_StrutsAndSprings";
        } else {
            mainStoryboardName = @"MainStoryboard_iPhone_StrutsAndSprings";
        }
        UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:mainStoryboardName bundle:nil];

        UIViewController *initialViewController = [mainStoryboard instantiateInitialViewController];
        self.window.rootViewController = initialViewController;
        [self.window makeKeyAndVisible];
    }

En outre, je définis la cible de déploiement du storyboard struts-and-springs sur iOS 5.1 et celle du storyboard autolayout sur Project SDK (iOS 6.0).

Je voulais vraiment faire le changement avant que le défaut dans storyboard soit chargé, dans willFinishLaunchingWithOptions: mais cela se traduit par une "NSInvalidUnarchiveOperationException", raison: "Impossible d'instancier la classe nommée NSLayoutConstraint", peu importe ce que j'ai essayé.


3
2018-01-17 12:03



Essayez d'utiliser RRAutoLayout: https://github.com/RolandasRazma/RRAutoLayout Il s'agit du backport iOS6 AutoLayout sur iOS5.


2
2017-12-13 03:04



J'ai trouvé le réglage de la taille de la vue principale de Xib sur Freeform, puis l'utilisation de la fonction de redimensionnement automatique est un régal. Aucune erreur dans le code pour un problème d'affichage.


0
2018-01-02 09:06