Skip to content Skip to sidebar Skip to footer

Uicontentsizecategorydidchange Notification Cause Childviewcontroller Layout Again

uk In the spirit of the new iOS adaptive philosophy, the SDK itself is giving us a new (or an old modified) View Controller that is really adaptive: the UISplitViewController.

"UISplitViewController is really a workhorse to be used in iOS 8" (from WWDC 2014 session "What's New in Cocoa Touch").

The big news aboutUISplitViewController ("Split") in iOS8 is that it is not limited to the iPad anymore: we can now use it on the iPhone, too. We don't have to think (and code) anymore about "which device we are on?".

Collapsed

The first thing we note is a completely new (read-only) property that indicates the display mode of the split:

If that property is false the Split has the same appearance of the previous versions (< 8 on iPad) with two children view controllers (VC): the primary and the secondary. If the property is true (the split is collapsed) it has only a VC and the secondary does not exist anymore. This is the new state, when the Split behaves similarly to a single UINavigationController.

Note that if the Split is in the expanded state, it can possibly continue to show a single VC, but it is alsocapable of showing two. On the other hand it is not capable to show two VCs at the same moment when it is in the collapsed state.

How does the split decide to be collapsed or expanded?

The UISplitViewController decides to be expanded or collapsed based on its current trait collection (UITraitCollection)  (see our article about class sizes for details).

The rule is simple:

  • if the horizontal class size is compact theUISplitViewController is in collapsed mode
  • if the horizontal class size is regular theUISplitViewControlleris in expanded mode

For an app running on the iPhone thus the Split is collapsed in all orientations (but we will see shortly how to possibly modify this behavior).

showDetailViewController

In our project example (downloadable at the end of the article) we use the new APIshowDetailViewController to change the content of the detail child of the Split (we already spoke about showViewController and showDetailViewController in this article). Let us compare this with the code we used in the past.

Showing a new view controller in split detail (<= iOS7):

Showing a new view controller in split detail (>= iOS8):

The big difference here is that in the last case (iOS8) we instantiate a completely new detail VC instead of simply changing the photo of the current one (as in the first example). (Note that we instantiate from the storyboard but we could also use the init and configure the VC programmatically).

In theory we can use the first code also in iOS8:

but we should make assumption on the current configuration ("we are inside a split"), and the real code is more complicated because in the collapsed state a VC of classPhotoViewController could not exist.

Also Apple in his Sample Code (AdaptivePhotosAnAdaptiveApplication) instantiate the VC every time with code like this:

We think that the overload to reallocate every time a new VC can be  a price to pay in order to be really "adaptive". Any comment and suggestion on this topic will be welcomed.

 Do you want a Split expanded on the iPhone too?

Now you can have it.

We said that the state of the split (collapsed or expanded) depends on the current trait collection of theUISplitViewController. What if we could make the split believe it is in horizontal regular class when it is really in a compact one?

A container view controller can override the trait collection of a child view controller using the new method:

Thus we implement a (very simple) container view controller that contains only the split  and override its trait collection.

This is the code of the container class, note that we override  the traits only when we are in landscape orientation (it's okay to be collapsed in portrait):

Note that we set only the horizontal size class of the current trait (line 30 and line 9), so the other values (as the vertical dimension class) of the trait collection remain untouched.

Then we add this code to the app delegate:

A split collapsing

When the split moves from collapsed to expanding state, and viceversa, it calls our delegate object and we have the opportunity to modify this behaviour. (in our app we see this transition when we rotate the iPhone).

When the split collapses it gives us a chance to make something with the current secondary VC (that is going to be deleted). In this phase it calls the following delegate method:

If this method return false (or is not implemented at all) the split calls the methodcollapseSecondaryViewController:forSplitViewController of the primary VC so that it has a chance to do something. For example if the primary is a UINavigationController, it pushes the secondary on the stack as the top VC (other VCs do nothing in this case).

If we return true the split simply leaves the primary as the new single VC.

In the example app we return true from this method when no photo is selected in the primary VC and thus the secondary is empty, so it would not be useful to show it as the the new primary VC.

A split expanding

When a split expands it needs the new VC to put it in the new secondary section of the interface. In this phase it calls the delegate method:

If we return nil, the split calls the methodseparateSecondaryViewControllerForSplitViewController of the primary VC to obtain the new secondary. For example if the primary is a UINavigationController, it pops the last VC from its stack and returns it to the split.

If we return a new VC, this is used as the new secondary VC.

In the example app we use this method when no photo is selected and we want to show a special empty VC to remark this (it is a simple PhotoViewController with no photo inside).

Other interesting properties

There is a new property that we can use in an expanded Split to force the visibility of the two VCs:

With possible values:

And now it is also possible to modify the width of the primary/secondary sections using some new properties, such as:

by which we can set the proportion of the total width to assign to the primary controller.

The code

  • Github

splitviewcontroller

EDIT 18 April 2016:

GitHub project now updated to Swift 2.2 (XCode 7.3)

Valerio Ferrucci

Valerio Ferrucci (valfer) develops software on Apple Macintosh since the 1990s until today for MacOS, OSX and, since some years, iOS. He is also a Web (PHP/MySQL/JS/CSS) and Android Developer.

More Posts - Website

Follow Me:
Twitter Facebook LinkedIn

padillahingivend.blogspot.com

Source: http://coding.tabasoft.it/ios/the-new-uisplitviewcontroller/

Postar um comentário for "Uicontentsizecategorydidchange Notification Cause Childviewcontroller Layout Again"