Quelle est la meilleure façon de profiter des nouvelles fonctionnalités de mise en page automatique d'iOS 6 tout en offrant une compatibilité avec les appareils plus anciens sur les versions antérieures d'iOS?
Quelle est la meilleure façon de profiter des nouvelles fonctionnalités de mise en page automatique d'iOS 6 tout en offrant une compatibilité avec les appareils plus anciens sur les versions antérieures d'iOS?
Réponses:
La mise en page automatique peut être activée ou désactivée sur chaque fichier .storyboard ou .xib. Sélectionnez simplement le fichier particulier et modifiez la propriété "Utiliser la mise en page automatique" à l'aide de l'inspecteur de fichiers dans Xcode:
L'utilisation de fichiers d'interface activés pour la mise en page automatique 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: Disposition automatique sur les versions iOS antérieures à 6.0
L'une de vos options pour utiliser la mise en page automatique dans un projet tout en préservant la compatibilité avec iOS4-5 consiste à créer deux cibles : une pour la cible de déploiement iOS 6.0 et une pour une version iOS antérieure, par exemple:
Vous pouvez également créer deux versions pour chacun de vos fichiers storyboard et XIB et utiliser la mise en page automatique activée avec la cible 6.0 et l'autre avec la cible héritée, par exemple:
Vous ajoutez ensuite MainStoryBoardAutoSize aux phases de construction de la cible iOS6 et l'autre fichier à la cible iOS4. Vous pouvez en savoir plus sur l'utilisation de plusieurs cibles ici .
EDIT: Comme le souligne la réponse de marchinram , si vous chargez vos fichiers de storyboard à partir du code et n'utilisez pas le paramètre "Main Storyboard" dans Xcode pour définir le storyboard initial, vous pouvez utiliser une seule cible.
Pour moi, le coût de la complexité supplémentaire de la maintenance de plusieurs cibles et fichiers d'interface semble l'emporter sur les avantages de l'utilisation de la mise en page automatique. À l'exception de quelques cas particuliers, il est probablement préférable d'utiliser le dimensionnement automatique (ou layoutSubViews à partir du code) exclusivement si la compatibilité iOS4-5 est requise.
Avez-vous vraiment besoin de deux cibles? Je l'ai fait fonctionner comme ça, j'ai 2 storyboard comme Imre Kelényi l'a dit, l'un avec les mises en page automatiques activées et l'autre sans, puis dans le délégué de l'application, je vérifie simplement quelle version ils utilisent et sélectionnez 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 également mais me semble exagéré
SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO
est exagéré. Testez simplement une classe iOS 6 uniquement contre zéro. Voir developer.apple.com/library/mac/#documentation/developertools/…
Si les différences de disposition ne sont pas importantes, il est beaucoup plus facile d'utiliser des ressorts et des entretoises pour positionner les éléments.
Inspiré par l'idée de cible unique de @ marchinram, c'est la solution que j'ai finalement trouvée. Deux storyboards, un pour les jambes de force et les ressorts et un pour la mise en page automatique. Dans le résumé de la cible, j'ai défini le storyboard de mise en page automatique par défaut. Ensuite, dans appDelegate, je vérifie si je dois charger le storyboard à jambes et ressorts pré-6.0 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, j'ai défini la cible de déploiement du storyboard struts-and-springs sur iOS 5.1 et celle du storyboard de mise en page automatique sur Project SDK (iOS 6.0).
Je voulais vraiment faire le changement avant que la valeur par défaut dans le storyboard ne soit chargée, 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é.
Essayez d'utiliser RRAutoLayout: https://github.com/RolandasRazma/RRAutoLayout C'est le backport iOS6 AutoLayout vers iOS5.