Extending the UIModal Transitions
On of the nice things about the UINavigationController is that it will keep track of the view controllers that have been presented which in turn permits the application to dismiss a controller and return to the previous one. The only problem I faced was was altering the transition animations being used to present and dismiss the views. This is not such a big problem when using OS3.0 and above as Apple have now provided a property to change transition animation, though it is a bit limited (see below):
modalTransitionStyle
The transition style to use when presenting the current view controller modally.@property (nonatomic, assign) UIModalTransitionStyle modalTransitionStyle
UIModalTransitionStyleCoverVertical
When the view controller is presented, its view slides up from the bottom of the screen. On dismissal, the view slides back down. This is the default transition style.UIModalTransitionStyleFlipHorizontal
When the view controller is presented, the current view initiates a horizontal 3D flip from right-to-left, resulting in the revealing of the new view as if it were on the back of the previous view. On dismissal, the flip occurs from left-to-right, returning to the original view.UIModalTransitionStyleCrossDissolve
When the view controller is presented, the current view fades out while the new view fades in at the same time. On dismissal, a similar type of cross-fade is used to return to the original view.
There are more transition animations provided by the OS, these have been available to users for OS2.0, so why not support them as well? Another problem is lack of support for altering these animations OS versions prior to OS3.0.
What I really wanted was the ability to play any of the transition provided by the OS and that the transitions to be the same no matter what version the OS the user was running and that’s what I set out to create.
The first question I had was where to put the code? It had to be easily available to my derived View Controllers and also be easy to remove. There where a couple of options 1) derive a new class off the UIViewController and inherit form that or 2) extend the UIViewController provided by UIKit. One of the nice features of Objective-C (if you don’t know) is the ability to extend a class’s functionality, providing an easy way to integrate code into a class even if you don’t have the original source code. I picked the later method as it would permit the additional code to be available to any of the UIViewControllers in my project all I had to do was include the extended class’s header in the .m file and the code could be used.
Below is the header file that I created to extend the UIKit UIViewController:
//
// UIViewController-Extended.h
//
// Created by Robert on 17/12/2009.
//
#import <UIKit/UIKit.h>
typedef enum
{
UIViewControllerAnimationTransitionNone = 0,
UIViewControllerAnimationTransitionFade,
UIViewControllerAnimationTransitionPushFromTop,
UIViewControllerAnimationTransitionPushFromRight,
UIViewControllerAnimationTransitionPushFromBottom,
UIViewControllerAnimationTransitionPushFromLeft,
UIViewControllerAnimationTransitionMoveInFromTop,
UIViewControllerAnimationTransitionMoveInFromRight,
UIViewControllerAnimationTransitionMoveInFromBottom,
UIViewControllerAnimationTransitionMoveInFromLeft,
UIViewControllerAnimationTransitionRevealFromTop,
UIViewControllerAnimationTransitionRevealFromRight,
UIViewControllerAnimationTransitionRevealFromBottom,
UIViewControllerAnimationTransitionRevealFromLeft,
UIViewControllerAnimationTransitionFlipFromLeft,
UIViewControllerAnimationTransitionFlipFromRight,
UIViewControllerAnimationTransitionCurlUp,
UIViewControllerAnimationTransitionCurlDown,
} UIViewControllerAnimationTransition;
@interface UIViewController (UIViewController_Expanded)
- (void)dismissModalViewControllerWithAnimatedTransition:(UIViewControllerAnimationTransition)transition;
- (void)presentModalViewController:(UIViewController*)viewController withAnimatedTransition:(UIViewControllerAnimationTransition)transition;
- (void)dismissModalViewControllerWithAnimatedTransition:(UIViewControllerAnimationTransition)transition WithDuration:(float)duration;
- (void)presentModalViewController:(UIViewController*)viewController withAnimatedTransition:(UIViewControllerAnimationTransition)transition WithDuration:(float)duration;
@end
The class interface is very simple, there is a list of the supported transition (these are all available) and four functions that are used invoke these transitions. Two functions to Present a modal and two to dismiss, unfortunately Objective -C does not support default function variables like c++ (correct me if I’m wrong) which is the reason for four functions where I would rather have two.
The class implementation is not as tidy (please feel to improve it) but it works, I’ve tested it on both OS3.0 / OS2.2 and have run into no issues as yet. The only real problem I have with it is that I have to turn views bounds clipping off, this was so that the UINavigationBar was displayed. If you don’t use a naviagion bar you can remove that code.
Example use:
//
// CustomViewController.m
//
#import "CustomViewController.h"
#import "UIViewController-Extended.h"
@implementation CustomViewController
...
// -------------------------------------------------------------------
// display the setup view controller
// -------------------------------------------------------------------
- (IBAction) displaySetupPage:(id)_sender
{
if ( setupController == nil )
{
setupController = [[CustomSetupController alloc] initWithNibName:@"Setup" bundle:nil];
}
[self presentModalViewController:controller withAnimatedTransition:UIViewControllerAnimationTransitionFlipFromRight];
}
...
@end
As always the source is provided as is and use it at your own risk, feel free to alter and extend as you see fit. Have fun.
Download : UIViewController-Extended.h, UIViewController-Extended.m
Sample Project : UIModuleTransitionSample


