16

Ich gehe zu UIPresentationController basierte Präsentationen für meine View-Controller, aber habe ein wenig Verwirrung mit der API gerissen.Adaptive UIPresentationController Basierend auf Ansichtsgröße

Ich habe eine benutzerdefinierte Sidebar Stil Ansicht Controller-Präsentation (ähnlich der LookInside WWDC 2014 Demo-Code).

Diese Klasse Cluster (UIPresentationController, UIViewControllerTransitioningDelegate und UIViewControllerAnimatedTransitioning) einen View-Controller als eine Seitenleiste von der Kante des Bildschirms auf Liniengrößenklasse Ansichten, und stellt die gleiche Ansicht Controller als Vollbild auf kompakte Größe Klassenansichten.

Das Testen auf dem resizierbaren iPad-Ziel zeigt das korrekte Verhalten: Ich setze die horizontale Größenklasse auf "Kompakt" und mein View-Controller wechselt von Sidebar auf Vollbild.

Allerdings möchte ich mehr Granularität. Ich möchte die Sidebar-ähnliche View-Controller-Präsentation auf iPhone 6 und 6+ verwenden, wenn sich das Gerät im Querformat befindet, und die Vollbild-Präsentation für alle iPhones im Hochformat verwenden.

So in meiner Methode

- (void) viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator 

implementiert ich eine gewisse Logik zu erkennen, ob die Sidebar zu viel des Bildschirms einnehmen wird, sagen wir, ich verwenden Sie die folgende Bedingung:

//If my sidebar is going to occupy more than half the new width of the view... 
if(self.sidebarTransitionController.width > size.width/2.0) 
{ 
    //Override the presentation controller's trait collection with Compact horizontal size class 
    sidebarPresentationController.overrideTraitCollection = [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact]; 
} 
else 
{ 
    //Otherwise override the trait collection with Regular 
    sidebarPresentationController.overrideTraitCollection = [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassRegular]; 

} 

aber dies tut nichts. Die Dokumentation für UIPresentationController.overrideTraitCollection Zustände:

Mit dieser Eigenschaft alle Merkmale angeben, die auf die dargestellten und präsentiert View-Controller anwenden möchten. Die Eigenschaften, die Sie angeben, überschreiben alle vorhandenen Eigenschaften, die derzeit für die View-Controller gelten. Der Standardwert dieser Eigenschaft ist null.

Das Zuweisen eines neuen Werts zu dieser Eigenschaft bewirkt, dass der Präsentationscontroller in den neuen Satz von Merkmalen übergeht, was zu Animationen für die dargestellte Oberfläche führen kann.

Das Zuweisen des neuen Werts zum Präsentationscontroller führt nicht dazu, dass sich meine dargestellte Schnittstelle in irgendeiner Weise ändert. (Auch wenn ich die overrideTraitCollection zuweisen, wenn die UIPresentationController aus dem UIViewControllerTransitioningDelegate Objekt erstellt wird.)

Was fehlt mir? Ist es möglich, eine adaptive Präsentation mit UIPresentationController auf einer feineren Ebene durchzuführen?

Antwort

1

Ist es möglich, adaptive Präsentation mit UIPresentationController auf einer granulareren Ebene durchzuführen?

Nicht leicht.

Ich schlage vor, eine dieser Optionen:

  1. auf Kontrolle Aufgeben und UIKit begrenzte Adaptivität akzeptieren: Sie auf eine Vollbilddarstellung ändern oder einen anderen View-Controller für eine bestimmtes Merkmal Sammlung präsentieren. Damit kannst du deine App schneller versenden.

  2. Verwenden Sie Präsentationen, aber arbeiten Sie gegen UIKit. Eine Möglichkeit besteht darin, viewWillTransitionToSize:withTransitionCoordinator: zu überschreiben und den präsentierten Ansichtscontroller zu schließen und erneut darzustellen, wobei Sie alle gewünschten Änderungen vornehmen, z. B. einen anderen Präsentationsstil oder Präsentationscontroller bereitstellen. Dies könnte zu guten Ergebnissen führen, ohne zu viel Zeit in Anspruch zu nehmen.

  3. Verwenden Sie den View Controller Containment. Dies ist die niedrigste Stufe, die Sie erreichen können, während Sie sich an die bewährten Methoden von UIKit halten. Ihr Hauptansicht-Controller wird zum untergeordneten Element eines Containeransicht-Controllers, und anstatt Sie zu präsentieren, bitten Sie den Container, den anderen View-Controller anzuzeigen. Gehen Sie damit, wenn die App benutzerdefiniert und exquisit sein sollte, und Sie können die Zeit verbringen, um es genau richtig zu machen.

1

Verwendung:

- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller 
                   traitCollection:(UITraitCollection *)traitCollection NS_AVAILABLE_IOS(8_3); 

Es auf Rotation genannt wird, selbst wenn die Größenklasse nicht geändert hat, so ist ein guter Ort, Sie Idiom/Orientierung spezifische Anpassung zu tun. Denken Sie daran, dass das iPhone 6 im gezoomten Modus laufen kann.

0

Ich stieß auf das gleiche Problem. Es ist möglich, die Geräteausrichtung aus den Größenklassen zu interpretieren, wenn auch nicht ganz eindeutig, aber das Folgende funktionierte für meine Zwecke.

Von Programming iOS 9: Dive Deep into Views, View Controllers and Frameworks, ein ausgezeichnetes Buch voll von wichtigen Details wie folgt aus:

horizontalSizeClass, verticalSizeClass

A UIUserInterfaceSizeClass Wert, entweder .Regular oder .Compact. Diese heißen Größenklassen. Die Größenklassen, in Kombination, haben folgende Bedeutung:

sowohl vertikale als auch horizontale Größenklassen sind .Regular: Wir sind auf einem iPad läuft

Die vertikale Größenklasse ist .Regular, aber die horizontale Größenklasse ist .Compact: Wir laufen auf einem iPhone mit der App im Hochformat. (Alternativ könnten wir auf einem iPad in einer iPad-Multitasking-Konfiguration mit Splitscreen laufen; siehe Kapitel 9).

Sowohl die vertikalen als auch die horizontalen Größenklassen sind .Compact: Wir laufen auf einem iPhone (außer iPhone 6 plus) mit der App im Querformat. Die vertikale Größenklasse ist .Compact und die horizontale Größenklasse ist .Regular: Wir laufen auf einem iPhone 6 plus im Querformat.

z.B. im View Controller:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
    if segue.identifier == "ShowComposeView" { 
     segue.destinationViewController.presentationController!.delegate = self 
     segue.destinationViewController.modalPresentationStyle = .PageSheet 
    } 
} 

func adaptivePresentationStyleForPresentationController(controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle { 
    // If we do an adaptive presentation, and adapt from Page Sheet to Form Sheet, 
    // then on iPhone 6 we will get the nice rounded corners of the nav bar 
    // in both portrait and landscape. (From pg. 298 of Programming iOS 9) 

    // We want this behaviour on iPhone in Portrait orientation only. 
    if traitCollection.horizontalSizeClass == .Compact && traitCollection.verticalSizeClass == .Regular { 
     return .FormSheet 
    } 
    else { 
     return .PageSheet 
    } 
}