2014-09-05 15 views
29

Ich habe ein Layout mit vier Tasten. Im Portrait sollten sie übereinander gezeigt werden. In der Landschaft sollten sie in zwei Spalten mit jeweils zwei Knöpfen sein.Programmgesteuert zwei verschiedene Layouts mit Größenklassen implementieren

auf die Schaltflächen in Code umzusetzen - wirklich einfache Sachen:

UIButton *btn1 = [[UIButton alloc] init]; 
[self.view addSubview: btn1]; 

UIButton *btn2 = [[UIButton alloc] init]; 
[self.view addSubview: btn2]; 

UIButton *btn3 = [[UIButton alloc] init]; 
[self.view addSubview: btn3]; 

UIButton *btn4 = [[UIButton alloc] init]; 
[self.view addSubview: btn4]; 

NSDictionary *views = NSDictionaryOfVariableBindings(btn1, btn2, btn3, btn4); 

[btn1 setTranslatesAutoresizingMaskIntoConstraints:NO]; 
[btn2 setTranslatesAutoresizingMaskIntoConstraints:NO]; 
[btn3 setTranslatesAutoresizingMaskIntoConstraints:NO]; 
[btn4 setTranslatesAutoresizingMaskIntoConstraints:NO]; 

// portrait constraints 
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(50)-[btn1]-(50)-|" 
                   options:0 metrics:nil views:views]]; 
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(50)-[btn2]-(50)-|" 
                   options:0 metrics:nil views:views]]; 
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(50)-[btn3]-(50)-|" 
                   options:0 metrics:nil views:views]]; 
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(50)-[btn4]-(50)-|" 
                   options:0 metrics:nil views:views]]; 

[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[btn1]-[btn2]-[btn3]-[btn4]-(50)-|" 
                   options:0 metrics:nil views:views]]; 

Dies ist offensichtlich das Setup für Portrait-Layout ist. Früher hätte ich das Gerät und seine Ausrichtung bestimmt, um iPad und iPhone in ihren jeweiligen Ausrichtungen zu konkretisieren. Aber jetzt sollen wir Größenklassen verwenden. Wie kann ich feststellen, ob die Größenklasse "kompakt" ist ... und somit die entsprechenden Einschränkungen festlegen?

Antwort

16

In der Zwischenzeit habe ich eine gute Lösung gefunden. Da diese Frage so viele Upvotes enthält, dachte ich, ich würde es schnell beschreiben. Ich wurde von einer WWDC-Sitzung zu dieser Lösung inspiriert.

Ich bin zu Swift gegangen, also bitte entschuldigen Sie, dass der Code in swift sein wird - das Konzept ist jedoch dasselbe für Obj-C.

Sie beginnen mit drei Constraint-Arrays deklarieren:

// Constraints 
private var compactConstraints: [NSLayoutConstraint] = [] 
private var regularConstraints: [NSLayoutConstraint] = [] 
private var sharedConstraints: [NSLayoutConstraint] = [] 

Und Sie dann die Einschränkungen entsprechend füllen. Sie können dies beispielsweise in einer separaten Funktion tun, die Sie von viewDidLoad anrufen, oder Sie tun dies direkt in viewDidLoad.

Der wichtige Teil ist das Wechseln zwischen den Größenklassen und das Aktivieren/Deaktivieren der entsprechenden Einschränkungen.

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { 

    super.traitCollectionDidChange(previousTraitCollection) 

    if (!sharedConstraints[0].isActive) { 
     // activating shared constraints 
     NSLayoutConstraint.activate(sharedConstraints) 
    } 


    if traitCollection.horizontalSizeClass == .compact && traitCollection.verticalSizeClass == .regular { 
     if regularConstraints.count > 0 && regularConstraints[0].isActive { 
      NSLayoutConstraint.deactivate(regularConstraints) 
     } 
     // activating compact constraints 
     NSLayoutConstraint.activate(compactConstraints) 
    } else { 
     if compactConstraints.count > 0 && compactConstraints[0].isActive { 
      NSLayoutConstraint.deactivate(compactConstraints) 
     } 
     // activating regular constraints 
     NSLayoutConstraint.activate(regularConstraints) 
    } 
} 

Ich weiß, dass die Einschränkungen nicht zu denen in der Frage passen. Aber die Einschränkungen selbst sind irrelevant. Die Hauptsache ist, wie man zwischen zwei Mengen von Beschränkungen basierend auf der Größenklasse umschaltet.

Hoffe, das hilft.

+0

ummm, welche wwdc session war das? – Honey

33

Sie können die Merkmalssammlung der Ansicht untersuchen, um ihre horizontale und vertikale Größenklasse zu bestimmen.

if (self.view.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassCompact) { 
    ... 
} 

Implementieren der traitCollectionDidChange: Methode automatisch, wenn Änderungen ein Merkmal aufgrund der Autorotation genannt werden.

Weitere Informationen finden Sie unter UITraitCollection Class Reference und UITraitEnvironment Protocol Reference.

+0

in Ordnung, aber es ist nicht die Frage beantworten - wenn ich bereits Einschränkungen in Code deklariert und jetzt will ich zum Beispiel Portrait- und Landschafts iphone unterscheiden dann Wie sollte ich diesen Code reparieren? –

+0

Prüflogik sollte in 'viewWillLayoutSubviews()' platziert werden. – Protocole

0

TraitCollection funktioniert nur in iOS8. Deine App wird also auf iOS7 abstürzen. Verwenden Sie den folgenden Code, um sowohl iOS7 als auch iOS8 zu unterstützen

+3

Frage wurde markiert 'iOS8'. – KPM

2

Swift 4 Code für die akzeptierte Antwort:

if (self.view.traitCollection.horizontalSizeClass == .compact) { 
... 
} 
Verwandte Themen