Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nice slide transition between non-fullscreen and fullscreen UIViewController

I have a view controller which is not fullscreen (has a status bar) and want to present a modal view controller which is fullscreen.

If I hide the status bar at the beginning of the animation (parent's viewWillDisappear or modal's viewWillAppear) then for a moment the parent will be visible without a status bar, looking like a bug.

If I do it at the end of the animation (parent's viewDidDisappear or modal's viewDidAppear) then the status bar will be visible for a moment over the modal view, i.e. it won't appear as the modal view "covered it".

Is there a way to do this nicely?

edit:

One possibility would be to create a UIWindow with windowLevel=alert for at least the duration of the animation. The sample iAd ad seems to cover the status bar nicely without another window, so it must be possible somehow.

like image 491
Jaka Jančar Avatar asked Dec 11 '11 12:12

Jaka Jančar


People also ask

How do I make ViewController full screen?

Present ViewController in full screen To prevent this, the presentation style can be changed. To present the DetailViewController full screen, the modalPresentationStyle property of a view controller must be set to . fullScreen before it will be presented.

How to present a new view controller?

Right-click the control or object in your current view controller. Drag the cursor to the view controller you want to present. Select the kind of segue you want from the list that Xcode provides.


1 Answers

Another fun little project. This was the best I could come up with. It's not too bad if you don't mind using your own container controller to manage presenting/dismissing view controllers. I try to do things in a general way but this could be rolled into an app w/ the ContainerViewController if desired.

Note that I only implemented the equivalent of UIModalTransitionStyleCoverVertical. You can customize the animation however you like as well.

Relevant animation code:

- (void)presentViewController:(UIViewController *)viewControllerToPresent
{   
    // do nothing if no controller
    if (!viewControllerToPresent) return;

    [__viewControllers addObject:viewControllerToPresent];
    CGRect toFrame = viewControllerToPresent.view.frame;
    toFrame.origin = CGPointMake(0, CGRectGetMaxY(self.view.bounds));
    viewControllerToPresent.view.frame = toFrame;

    [UIView transitionWithView:self.view
                      duration:0.2
                       options:UIViewAnimationOptionTransitionNone
                    animations:^{
                        [[UIApplication sharedApplication] setStatusBarHidden:viewControllerToPresent.wantsFullScreenLayout withAnimation:UIStatusBarAnimationSlide];
                        [self.view addSubview:viewControllerToPresent.view];
                        viewControllerToPresent.view.frame = [UIScreen mainScreen].applicationFrame;
                    }
                    completion:nil];
}

- (void)dismissViewController
{
    // nothing to dismiss if showing first controller
    if (__viewControllers.count <= 1) return;

    UIViewController *currentViewController = [__viewControllers lastObject];
    UIViewController *previousViewController = [__viewControllers objectAtIndex:__viewControllers.count - 2];

    [UIView transitionWithView:self.view
                      duration:0.2
                       options:UIViewAnimationOptionTransitionNone
                    animations:^{
                        [[UIApplication sharedApplication] setStatusBarHidden:previousViewController.wantsFullScreenLayout withAnimation:UIStatusBarAnimationSlide];
                        CGRect toFrame = currentViewController.view.frame;
                        toFrame.origin = CGPointMake(0, CGRectGetMaxY(self.view.bounds));
                        currentViewController.view.frame = toFrame;
                    }
                    completion:^(BOOL finished) {
                        [currentViewController.view removeFromSuperview];
                        [__viewControllers removeLastObject];
                    }];
}
like image 102
XJones Avatar answered Sep 28 '22 00:09

XJones