Was ist der beste Weg, um die neuen Funktionen für das automatische Layout von iOS 6 zu nutzen und gleichzeitig die Kompatibilität mit älteren Geräten auf früheren Versionen von iOS zu gewährleisten?
Was ist der beste Weg, um die neuen Funktionen für das automatische Layout von iOS 6 zu nutzen und gleichzeitig die Kompatibilität mit älteren Geräten auf früheren Versionen von iOS zu gewährleisten?
Antworten:
Autolayout kann für jede .storyboard- oder .xib-Datei aktiviert oder deaktiviert werden. Wählen Sie einfach die jeweilige Datei aus und ändern Sie die Eigenschaft "Autolayout verwenden" mithilfe des Dateiinspektors in Xcode:
Die Verwendung von Autolayout-fähigen Schnittstellendateien, bei denen das Bereitstellungsziel auf eine iOS-Version vor 6.0 festgelegt wurde, führt zu Kompilierungsfehlern, z.
Fehler in MainStoryboard.storyboard: 3: Automatisches Layout unter iOS-Versionen vor 6.0
Eine Ihrer Optionen zur Verwendung von Autolayout in einem Projekt und zur Wahrung der Kompatibilität mit iOS4-5 besteht darin, zwei Ziele zu erstellen : eines für das Bereitstellungsziel iOS 6.0 und eines für eine frühere iOS-Version, z.
Sie können auch zwei Versionen für jede Ihrer Storyboard- und XIB-Dateien erstellen und das mit dem 6.0-Ziel aktivierte Autolayout und das andere mit dem Legacy-Ziel verwenden, z.
Anschließend fügen Sie MainStoryBoardAutoSize zu den Erstellungsphasen des iOS6-Ziels und die andere Datei zum iOS4-Ziel hinzu. Sie können mehr über die Verwendung von mehreren Zielen lernen hier .
BEARBEITEN : Wie die Antwort von Marchinram zeigt, können Sie ein einzelnes Ziel verwenden, wenn Sie Ihre Storyboard-Dateien aus Code laden und die Einstellung "Haupt-Storyboard" in Xcode nicht zum Festlegen des anfänglichen Storyboards verwenden.
Für mich scheinen die Kosten für die zusätzliche Komplexität der Verwaltung mehrerer Ziele und Schnittstellendateien die Vorteile der Verwendung von Autolayout zu überwiegen. Mit Ausnahme einiger Sonderfälle ist es wahrscheinlich viel besser, die einfache alte automatische Größenanpassung (oder layoutSubViews aus Code) ausschließlich dann zu verwenden, wenn iOS4-5-Kompatibilität erforderlich ist.
Benötigen Sie wirklich zwei Ziele? Ich habe es so gemacht, ich habe 2 Storyboards, wie Imre Kelényi sagte, eines mit aktivierten automatischen Layouts und das andere ohne, dann überprüfe ich im App-Delegaten einfach, welche Version sie verwenden und wähle das richtige Storyboard aus:
#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
2 Ziele zu haben funktioniert auch, scheint mir aber übertrieben
SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO
ist übertrieben. Testen Sie einfach eine reine iOS 6-Klasse gegen Null. Siehe developer.apple.com/library/mac/#documentation/developertools/…
Wenn die Layoutunterschiede nicht groß sind, ist es viel einfacher, Federn und Streben zum Positionieren von Elementen zu verwenden.
Inspiriert von @ Marchinrams einziger Zielidee, ist dies die Lösung, die ich mir schließlich ausgedacht habe. Zwei Storyboards, eines für Federbeine und eines für Autolayout. In der Zielzusammenfassung habe ich das Autolayout-Storyboard als Standard festgelegt. Dann überprüfe ich im AppDelegate, ob ich das Storyboard für Federbeine und Federn vor 6.0 doch laden muss:
- (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];
}
Außerdem habe ich das Bereitstellungsziel des Struts-and-Springs-Storyboards auf iOS 5.1 und das des Autolayout-Storyboards auf Project SDK (iOS 6.0) festgelegt.
Ich wollte den Wechsel unbedingt durchführen, bevor die Standardeinstellung im Storyboard in willFinishLaunchingWithOptions geladen wird. Dies führt jedoch zu einer 'NSInvalidUnarchiveOperationException'. Grund: 'Klasse mit dem Namen NSLayoutConstraint konnte nicht instanziiert werden, egal was ich versucht habe.
Versuchen Sie, RRAutoLayout zu verwenden: https://github.com/RolandasRazma/RRAutoLayout Es handelt sich um den AutoLayout-Backport für iOS6 zu iOS5.