在这种情况下,我建议使用自定义动画委托将 UINavigationController 子类化,并在内部这样做:
- (void)viewDidLoad
{
[super viewDidLoad];
self.delegate = [MainNavigationBarDelegate instance];
}
主 NavigationBarDelegate.h:
@interface MainNavigationBarDelegate : NSObject <UINavigationControllerDelegate, UIViewControllerAnimatedTransitioning>
+ (instancetype)instance;
@end
MainNavigationBarDelegate.m:
#import "MainNavigationBarDelegate.h"
@implementation MainNavigationBarDelegate
+ (instancetype)instance
{
static MainNavigationBarDelegate *delegate;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
delegate = [[MainNavigationBarDelegate alloc] init];
});
return delegate;
}
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC
{
return self;
}
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
return 0.3;
}
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
{
RootViewController *fromViewController = (RootViewController*)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
RootViewController *toViewController = (RootViewController*)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
NSUInteger fromIndex = [toViewController.navigationController.childViewControllers indexOfObject:fromViewController];
NSUInteger toIndex = [toViewController.navigationController.childViewControllers indexOfObject:toViewController];
BOOL scrollRight = toIndex > fromIndex;
// Get the size of the view area.
[transitionContext.containerView addSubview:fromViewController.view];
[transitionContext.containerView addSubview:toViewController.view];
CGFloat xOrigin;
if (scrollRight){
xOrigin = fromViewController.view.frame.size.width;
}
else {
xOrigin = -fromViewController.view.frame.size.width;
}
toViewController.view.frame = CGRectMake(xOrigin, toViewController.view.frame.origin.y, toViewController.view.frame.size.width, toViewController.view.frame.size.height);
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
toViewController.view.frame = CGRectMake(0, toViewController.view.frame.origin.y, toViewController.view.frame.size.width, toViewController.view.frame.size.height);
fromViewController.view.frame = CGRectMake(-xOrigin, fromViewController.view.frame.origin.y, fromViewController.view.frame.size.width, fromViewController.view.frame.size.height);
} completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
if (scrollRight){
fromViewController.view.frame = CGRectMake(0, fromViewController.view.frame.origin.y, fromViewController.view.frame.size.width, fromViewController.view.frame.size.height);
[toViewController.navigationController.view addSubview:fromViewController.view];
[toViewController.navigationController.view sendSubviewToBack:fromViewController.view];
}
}];
}
@end