UIModalTransitionStylePartialCurl with UITabBarController

I’ve scoured StackOverflow (and the Internet) for a solution to this problem. The question has been asked many times, but as you note, never sufficiently answered. Many solutions give an acceptable solution if it is unimportant whether, e.g., a lower toolbar curls up as well.

Others have provided a solution using UIView animations / CoreAnimation rather than UIModalTransitionStylePartialCurl as a modal transition style; this is at worst a solution not allowed in the App Store, and at best is not quite the same effect as one gets from UIModalTransitionStylePartialCurl (e.g. the shape of the curl is different).

None of these solutions have provided an answer that mimics Apple’s solution in the Maps app (i.e., using UIModalTransitionStylePartialCurl but leaving an un-curled UIToolbar at the bottom of the screen).

I will continue in this tradition of incomplete answers, since you ask about a UITabBarController and my solution doesn’t specifically address that case. It does, however, solve the problem I had, which was to get a half page curl with an un-curled toolbar at the bottom.

There must be a more elegant way to do this, but this is how I managed.

The rootViewController of my AppDelegate is a subclass of UIViewController, which I’ll call TAContainerViewController. TAContainerViewController manages a) the actual contents of the screen (the “stuff to be curled”), TAContentViewController, and b) the contents “behind” the TAContentViewController (e.g. settings), which I’ll call TAUnderCurlViewController.

My instance of TAContainerViewController had properties for a TAContentViewController and a TAUnderCurlViewController. The UIView that was my content was a subview of TAContentViewController‘s view property; likewise what the user sees under the curl is the view property of the TAUnderCurlViewController.

In the init method of TAContainerViewController I make sure to do the following:

    _underCurlVC.modalTransitionStyle = UIModalTransitionStylePartialCurl;

And to curl the contents to reveal under the page, I set up an action that calls this code:

    [self.contentVC presentModalViewController:self.underCurlVC animated:YES];`

where self is the TAContainerViewController, contentVC is an instance of TAContentViewController, and underCurlVC is an instance of TAUnderCurlViewController.

To dismiss the view, simply [self.contentVC dismissModalViewControllerAnimated:YES];.

Some strangeness seems to occur with the frame of contentVC when the modal view is dismissed, so I manually reset the frame when the modal view is dismissed.

I’ve posted a sample project with more details on Github. Hopefully someone can take this and turn it into a slightly more elegant solution, or expand it to work with a UINavigationController or UITabBarController. I think the trick is to pull the View Controllers out of the well-defined relationships in the Cocoa subclasses, so maybe subclassing those specialty View Controllers would do it.

Leave a Comment