Aktivieren des automatischen Layouts in iOS 6 bei gleichzeitiger Abwärtskompatibilität mit iOS 5

153

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?

sglantz
quelle
+1. Wo können Sie das herausfinden? Irgendeine Ahnung ?
Janak Nirmal
@ Tennis Noch nicht. iOS 6 wird morgen (19.09.2012) offiziell veröffentlicht. Hoffentlich enthält das einige zusätzliche Dokumentationen zu diesem Thema.
Sglantz
Ich habe noch nichts gefunden. Neugierige würden gerne wissen!
Ben Kreeger
Ich denke nicht, dass das möglich wäre. Ähnlich wie Storyboards waren unter iOS4 nicht möglich.
Leo Natan
Abgesehen von der Bereitstellung von zwei NIB-Dateien sehe ich nicht, wie das möglich wäre. Aber ich stimme dir zu.
Leo Natan

Antworten:

120

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:

Autolayout-Eigenschaft im Dateiinspektor

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.

Geben Sie hier die Bildbeschreibung ein

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.

Geben Sie hier die Bildbeschreibung ein

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.

Imre Kelényi
quelle
29
Für das automatische Layout ist iOS 6 oder höher erforderlich. Es funktioniert nicht mit iOS 5! Bitte überprüfen Sie Ihre Ansprüche vor dem Posten. iOS 5 verfügt einfach nicht über die erforderlichen APIs (z. B. die Klasse NSLayoutConstraint). Wenn Sie mir nicht glauben, lesen Sie, was andere Benutzer erleben, wenn sie versuchen, Autolayout mit iOS 5 zu verwenden: stackoverflow.com/questions/11252057/… stackoverflow.com/questions/11198981/…
Imre Kelényi
1
Ja, ich glaube, Sie haben Recht. Ich glaube, ich habe es in einigen wwdc-Videos gehört, aber jetzt habe ich es auf einem iOS 5.0-Gerät getestet und es ist abgestürzt. Ich werde diese Videos durchgehen und prüfen, wo ich sie gehört habe. Trotzdem hast du Recht, dass sie unter iOS 5.0
Asad Khan
@ ImreKelényi Wie würden Sie dies an den App Store senden? Ich bin mit dem Prozess nicht besonders vertraut, aber ich dachte, Sie senden ein komprimiertes Archiv Ihrer .app-Datei. Erschwert es diesen Prozess überhaupt, zwei Ziele zu haben? Vielen Dank.
Crystal
47

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

Marchinram
quelle
1
Du hast recht. Dies funktioniert so lange, wie Sie Storyboards aus Code laden und nicht die Einstellung "Haupt-Storyboard" des Ziels in Xcode verwenden. Ich füge einen Verweis auf Ihre Antwort aus meinem Beitrag hinzu.
Imre Kelényi
SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TOist übertrieben. Testen Sie einfach eine reine iOS 6-Klasse gegen Null. Siehe developer.apple.com/library/mac/#documentation/developertools/…
matt
Ja, gute Punkte, ich habe nicht wirklich über Restaurierung
nachgedacht,
Ahem, benutze nicht willFinishLaunchingWithOptions - Ich habe eine "Beendende App wegen nicht erfasster Ausnahme" NSInvalidUnarchiveOperationException ", Grund:" Klasse mit dem Namen NSLayoutConstraint konnte nicht instanziiert werden ", die den Simulator unter iOS 5.1 ausführt. Das Problem tritt bei didFinishLaunchingWithOptions nicht auf.
Elise van Looij
4

Wenn die Layoutunterschiede nicht groß sind, ist es viel einfacher, Federn und Streben zum Positionieren von Elementen zu verwenden.

Reiches Apodaca
quelle
3

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.

Elise van Looij
quelle
0

Ich habe festgestellt, dass das Festlegen der Größe der Xibs-Hauptansicht auf Freiform und die Verwendung der automatischen Größenanpassung ein Vergnügen ist. Kein Durcheinander im Code für ein Ansichtsproblem.

Anonym
quelle