上一篇中写了rootViewController更改时的淡入动画,如果我们push界面也用上一篇中的方法.那么就会发现淡入动画和push自己本身的动画会同时进行.达不到预期的效果
[UIView transitionWithView:[[UIApplication sharedApplication] delegate].window duration:1 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
BOOL oldState = [UIView areAnimationsEnabled];
[UIView setAnimationsEnabled:NO];
[self.navigationController pushViewController:controller animated:YES]
[UIView setAnimationsEnabled:oldState];
} completion:nil];
要想实现只有淡入效果动画我们需要创建一个类,重写push动画
创建PushTransitionUtil类
PushTransitionUtil.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface PushTransitionUtil : NSObject<UIViewControllerAnimatedTransitioning>
@end
PushTransitionUtil.m
#import "PushTransitionUtil.h"
@interface PushTransitionUtil()<CAAnimationDelegate>
@property (nonatomic, strong)id<UIViewControllerContextTransitioning> transitionContext;
@end
@implementation PushTransitionUtil
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{
return 0.7;
}
// 转场动画的具体内容
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext{
self.transitionContext = transitionContext;
// 获取动画的源控制器和目标控制器
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView * container = transitionContext.containerView;
// 设置目标控制器的位置,并把透明度设为0,在后面的动画中慢慢显示出来变为1
toVC.view.frame = [transitionContext finalFrameForViewController:toVC];
toVC.view.alpha = 0;
// 都添加到container中。注意顺序
[container addSubview:toVC.view];
// 执行动画
[UIView animateKeyframesWithDuration:[self transitionDuration:transitionContext] delay:0 options:UIViewKeyframeAnimationOptionCalculationModeLinear animations:^{
// snapshotView.frame = toVC.avatarImageView.frame;
toVC.view.alpha = 1;
} completion:^(BOOL finished) {
//一定要记得动画完成后执行此方法,让系统管理 navigation
[transitionContext completeTransition:YES];
}];
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
//告诉 iOS 这个 transition 完成
[self.transitionContext completeTransition:YES];
[self.transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].view.layer.mask = nil;
[self.transitionContext viewControllerForKey:UITransitionContextToViewControllerKey].view.layer.mask = nil;
}
在接下来就是要自定义一个UINavigationController
#import "BaseNavigationViewController.h"
#import "PushTransitionUtil.h"
@interface BaseNavigationViewController ()<UINavigationControllerDelegate>
@end
@implementation BaseNavigationViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.delegate = self;
}
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC{
// 就是在这里判断是哪种动画类型
// 也可以判断是哪一个viewcongroller
if (operation == UINavigationControllerOperationPush){
return [PushTransitionUtil new]; // 返回push动画的类
}else{
return nil;
}
}
@end
网友评论