Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adaptive UIPresentationController Based on View Size

I'm moving over to UIPresentationController based presentations for my view controllers but have run into some confusion with the API.

I have a custom sidebar style view controller presentation (similar to the LookInside WWDC 2014 demo code).

This class cluster (UIPresentationController, UIViewControllerTransitioningDelegate, and UIViewControllerAnimatedTransitioning) presents a view controller as a sidebar from the edge of the screen on regular size class views, and presents the same view controller as full screen on compact size class views.

Testing this on the Resizable iPad target shows the correct behaviour: I set the horizontal size class to "Compact" and my view controller switches from sidebar to full screen.

However, I want more granularity. I would like to use the sidebar-style view controller presentation on iPhone 6 and 6+ when the device is in landscape orientation, and use the full-screen style presentation for all iPhones in portrait orientation.

So in my method

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

I implemented some logic to detect whether the sidebar will occupy too much of the screen, let's say I use the following condition:

//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];

}

However this does nothing. The documentation for UIPresentationController.overrideTraitCollection states:

Use this property to specify any traits that you want to apply to the presented and presenting view controllers. The traits you specify override any existing traits currently in effect for the view controllers. The default value of this property is nil.

Assigning a new value to this property causes the presentation controller to transition to the new set of traits, which could result in animations to the presented interface.

Assigning the new value to the presentation controller does not cause my presented interface to change in any way. (Even if I assign the overrideTraitCollection when the UIPresentationController is created from within the UIViewControllerTransitioningDelegate object.)

What am I missing? Is it possible to perform adaptive presentation with UIPresentationController on a more granular level?

like image 908
simeon Avatar asked Apr 09 '15 13:04

simeon


2 Answers

Is it possible to perform adaptive presentation with UIPresentationController on a more granular level?

Not easily.

I suggest one of these options:

  1. Give up on control and accept UIKit’s limited adaptivity: you can change to a full screen presentation or present a different view controller for a particular trait collection. Go with this to ship your app faster.

  2. Use presentations but work against UIKit. One way is to override viewWillTransitionToSize:withTransitionCoordinator: and dismiss and then re-present the presented view controller, making any changes you want such as providing a different presentation style or presentation controller. This could give okay results without taking too much time.

  3. Use view controller containment. This is about the lowest level you can go while sticking with UIKit best practices. Your main view controller becomes a child of a container view controller, and instead of presenting you ask the container to show the other view controller. Go with this if the app should be custom and exquisite, and you can spend the time to make it just right.

like image 118
Douglas Hill Avatar answered Nov 16 '22 21:11

Douglas Hill


Use:

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

It's called on rotation even if the size class hasn't changed so is a good place to do you idiom/orientation specific adaptation. Remember that iPhone 6 can run in zoomed in mode.

like image 1
malhal Avatar answered Nov 16 '22 19:11

malhal