How to present a half modal view controller over the top with iOS 7 custom transitions

johnsampson picture johnsampson · Apr 5, 2014 · Viewed 12.9k times · Source

How would I go about presenting a "half view" controller over the top of main view controller?

Requirements: - Present a second view controller that slides over the top of main view controller. - Second view controller should only show over half of the main view controller - Main view controller should remain visible behind second view controller (transparent background, not showing black underneath) - Second view controller should animate in with animation similar to modal vertical cover, or iOS 7 custom transition - User can still interact with buttons on main view controller when second view controller is active (i.e. second view controller does not cover the entire main view controller)r - Second view controller has its own complex logic (cannot be a simple view) - Storyboards, Segues, iOS 7 only - iPhone only, not iPad.

I have tried with modal view controller, but this does not allow interaction with main view controller. Can someone provide an example of how to do this with iOS7 custom transition or another method.

Answer

rdelmar picture rdelmar · Apr 5, 2014

One way to do it is to add the "half modal" controller as a child view controller, and animate its view into place. For this example, I created the "half modal" controller in the storyboard with a frame that's half the height of a 4" iPhone screen. You could use more dynamic methods to account for different screen sizes, but this should get you started.

@interface ViewController ()
@property (strong,nonatomic) UIViewController *modal;
@end

@implementation ViewController


- (IBAction)toggleHalfModal:(UIButton *)sender {
    if (self.childViewControllers.count == 0) {
        self.modal = [self.storyboard instantiateViewControllerWithIdentifier:@"HalfModal"];
        [self addChildViewController:self.modal];
        self.modal.view.frame = CGRectMake(0, 568, 320, 284);
        [self.view addSubview:self.modal.view];
        [UIView animateWithDuration:1 animations:^{
            self.modal.view.frame = CGRectMake(0, 284, 320, 284);;
        } completion:^(BOOL finished) {
            [self.modal didMoveToParentViewController:self];
        }];
    }else{
        [UIView animateWithDuration:1 animations:^{
            self.modal.view.frame = CGRectMake(0, 568, 320, 284);
        } completion:^(BOOL finished) {
            [self.modal.view removeFromSuperview];
            [self.modal removeFromParentViewController];
            self.modal = nil;
        }];
    }
}