ios 7 view with transparent content overlaps previous view

23,538

Solution 1

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.

Solution 2

I did this.

-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    [self.view setAlpha:0];
}

Do not forget re set alpha when come back.

- (void) viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    [self.view setAlpha:1];
}

Solution 3

I fixed it by doing this when initialising the view:

self.view.clipsToBounds = YES;

Solution 4

You might want to look into a new iOS7 feature that allows you to define your own custom UIViewController transitions. Look in the docs for UIViewControllerTransitioningDelegate. Also, here's a link to an article about it: http://www.doubleencore.com/2013/09/ios-7-custom-transitions/

Solution 5

Ah, now I understand the issue. You were right, seems to be caused by the previous UIViewController not being hidden after the transition (because of the new transition effect).

There doesn't seem to be any SDK method to control this behavior. Short of redesigning the app to not requiring the background be static, you'll probably have to roll your own navigation. OSNavigationController is a complete reimplementation of UINavigationController that might help you out. If they haven't updated to the iOS 7 transition, you'll probably be good to go. If they have you can always use an older version.

Share:
23,538
Edvardas
Author by

Edvardas

Updated on December 25, 2020

Comments

  • Edvardas
    Edvardas over 3 years

    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];