成功版的从左到右的Push动画
通过实现UINavigationControllerDelegate
,自定义转场动画 1.创建一个Pushtransition
#import <Foundation/Foundation.h>
@interface PushTransition : NSObject
@property(nonatomic,strong) id<UIViewControllerContextTransitioning>transitionContext;
@end
复制代码
.m文件
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "PushTransition.h"
@interface PushTransition ()<CAAnimationDelegate>
@end
@implementation PushTransition
- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext
{
return 0.3f;
}
// This method can only be a nop if the transition is interactive and not a percentDriven interactive transition.
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
{
self.transitionContext = transitionContext;
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
//不添加的话,屏幕什么都没有
UIView *containerView = [transitionContext containerView];
[containerView addSubview:fromVC.view];
[containerView addSubview:toVC.view];
CABasicAnimation *maskAnimation = [CABasicAnimation animationWithKeyPath:@"position.x"];
maskAnimation.fromValue = @(-toVC.view.frame.size.width/2.0);
maskAnimation.toValue = @(toVC.view.frame.size.width/2.0);
maskAnimation.duration = [self transitionDuration:transitionContext];
maskAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
maskAnimation.fillMode = kCAFillModeForwards;
maskAnimation.removedOnCompletion = NO;
maskAnimation.delegate = self;
[toVC.view.layer addAnimation:maskAnimation forKey:@"position"];
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
[self.transitionContext completeTransition:![self.transitionContext transitionWasCancelled]];
//去除mask
[self.transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].view.layer.mask = nil;
[self.transitionContext viewControllerForKey:UITransitionContextToViewControllerKey].view.layer.mask = nil;
}
@end
复制代码
2.设置navcontroller 代理
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = [UIColor redColor];
self.navigationController.delegate = self;
}
复制代码
3.在viewcontroller
实现代理
#pragma mark -UINavigationControllerDelegate
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC
{
if (operation == UINavigationControllerOperationPush) {
//返回我们自定义的效果
return (id)[[PushTransition alloc]init];
}
return nil;
}
复制代码
4.push跳转
- (IBAction)pushTransition:(id)sender {
SecondViewController *secondCtl = [self.storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
[self.navigationController pushViewController:secondCtl animated:YES];
}
复制代码
4.FAQ 此处有坑请小心,transition中的animationDidStop必须要有,否则你会发现所有的事件都响应不了.
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
[self.transitionContext completeTransition:![self.transitionContext transitionWasCancelled]];
//去除mask
[self.transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].view.layer.mask = nil;
[self.transitionContext viewControllerForKey:UITransitionContextToViewControllerKey].view.layer.mask = nil;
}
复制代码