ios 7 view with transparent content overlaps previous view

ios7, pushviewcontroller, uinavigationcontroller, xcode5

Solution

I solved the problem by implementing the new `UINavigationControllerDelegate` Method `animationControllerForOperation`.

For example:

- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController     *)navigationController
                              animationControllerForOperation:(UINavigationControllerOperation)operation
                                           fromViewController:(UIViewController *)fromVC
                                             toViewController:(UIViewController *)toVC
{

PushTransition* transition = [PushTransition new];
[transition setNavigationControllerOperation: operation];

return transition;
}

PushTransition is a class that implements the `UIViewControllerAnimatedTransitioning` protocol and the two methods transitionDuration and animateTransition from that protocol. Additionally, i have added a property to pass the operation (tells me if it is a push or pop transition).

Just put the animation code for moving the views into the animateTransition as follows:

// the containerView is the superview during the animation process.
UIView *container = transitionContext.containerView;

UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

UIView *fromView = fromVC.view;
UIView *toView = toVC.view;
CGFloat containerWidth = container.frame.size.width;

// Set the needed frames to animate.

CGRect toInitialFrame = [container frame];
CGRect fromDestinationFrame = fromView.frame;

if ([self navigationControllerOperation] == UINavigationControllerOperationPush)
{
    toInitialFrame.origin.x = containerWidth;
    toView.frame = toInitialFrame;
    fromDestinationFrame.origin.x = -containerWidth;
}
else if ([self navigationControllerOperation] == UINavigationControllerOperationPop)
{
    toInitialFrame.origin.x = -containerWidth;
    toView.frame = toInitialFrame;
    fromDestinationFrame.origin.x = containerWidth;
}

// Create a screenshot of the toView.
UIView *move = [toView snapshotViewAfterScreenUpdates:YES];
move.frame = toView.frame;
[container addSubview:move];

[UIView animateWithDuration:TRANSITION_DURATION delay:0
     usingSpringWithDamping:1000 initialSpringVelocity:1
                    options:0 animations:^{
                        move.frame = container.frame;
                        fromView.frame = fromDestinationFrame;
                    }
                 completion:^(BOOL finished) {
                     if (![[container subviews] containsObject:toView])
                     {
                         [container addSubview:toView];
                     }

                     toView.frame = container.frame;
                     [fromView removeFromSuperview];
                     [move removeFromSuperview];
                     [transitionContext completeTransition: YES];
                 }];

described it and you can you are done. Additionally you can make any push or pop animation you like.

Problem

Recently I updated my xcode project to work with iOS 7, but i faced a big problem. Because my whole application has only one background image (UIImageView added to key window) and all views are transparent, I face a problem when pushing UIViewController, because pushed view controller overlaps previous view (you can see it in the picture here: http://grab.by/qp0k). I can predict that this is because in iOS 7 push transition has been changed, because now it slides half a screen. Maybe anyone knows how to fix this issue? This is how I set my key windows ``` self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; UIImageView *background = [[UIImageView alloc]initWithFrame:[[UIScreen mainScreen] bounds]]; background.image = [UIImage imageNamed:@"background.png"]; UINavigationController *navi = [[UINavigationController alloc]initWithRootViewController:self.viewController]; self.window.rootViewContro‌​ller = navi; [self.window makeKeyAndVisible]; ``` Afterwards when user clicks on "start workout" button I push my next view as always: ``` workoutView *w = [[workoutView alloc]initWithNibName:@"workoutView" bundle:nil]; [self.navigationController pushViewController:w animated:YES]; ```

Original source

Related problems