2
votes

I'm using the new custom view controller transitions introduced in iOS 7 in combination with a UINavigationController. I implemented

-navigationController:animationControllerForOperation:fromViewController:toViewController:

in my UINavigationControllerDelegate, implemented the UIViewControllerAnimatedTransitioning protocol and the custom transition works beautifully.

However I'd like to prevent the shift animation in the navigation bar when pushing the view controller. Interestingly, the pop animation is fine and the navigation items are just alpha-faded instead of shifted. But the push animation shifts the navigation items from the right.

I found a partial solution by replacing -pushViewController:animated: with -setViewControllers:animated: and adding the new view controller to the viewControllers array. This does the correct alpha fading animation - EXCEPT for the very first time the view controller is pushed on the stack. Subsequent pops/pushes are fine.

Any idea how to achieve this effect? Calendar.app and Photos.app also implement this, so it should be possible (though it might be a specific behavior when using collection views).

1
I don't know if you're still having a problem here, but I'm unable to reproduce it. Can you provide more detail? When I specify a custom transition using animationControllerForOperation, the animation affects my content the way I'd expect, and the navigation bar fades (for both push and pops).Rob
It does fade but it also does a shift animation. I'll post my workaround.Ortwin Gentz

1 Answers

0
votes

I've written a workaround that removes all position animations from navigation bar subviews:

@implementation UIView (FTNavigationBar)

static CGFloat leftMargin = 8;

- (void)removePushAnimation {
    CAAnimation *animation = [self.layer animationForKey:@"position"];
    if (animation) {
        if ([animation isKindOfClass:CABasicAnimation.class] && ((CABasicAnimation*)animation).fromValue) {
            CGPoint point = [((CABasicAnimation*)animation).fromValue CGPointValue];
            CGFloat halfSuperWidth = [self superviewOfKind:FTNavigationBar.class].bounds.size.width / 2;
            if ((fabs(point.x - halfSuperWidth) < 2 && fabs(self.center.x - halfSuperWidth) > 2) || fabs(point.x - self.frame.size.width/2 - leftMargin) < 2) {
                self.layer.position = point;
            }
        }
        [self.layer removeAnimationForKey:@"position"];
    }
    for (UIView *subview in [self subviews]) {
        [subview removePushAnimation];
    }
}

@end