pop push 自定义转场效果


push转场自定义:同理可得pop的



控制器需要实现的方法:


pop返回的时候:需要加载一个手势:


然后实现代理方法:




首先需要实现协议

在要添加自定义效果的视图控制器中实现代理协议UINavigationControllerDelegate


- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    self.navigationController.delegate = self;

}

实现代理方法

#pragma mark -UINavigationControllerDelegate
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC
{
    if (operation == UINavigationControllerOperationPush) {
        //返回我们自定义的效果
        return [[PushTransition alloc]init];
    }
    else if (operation == UINavigationControllerOperationPop){
        return [[PopTransition alloc]init];
    }
    //返回nil则使用默认的动画效果
    return nil;

}


注:PushTransition、PopTransition为具体效果的实现

PushTransition的实现
这种效果的实现类需要实现UIViewControllerAnimatedTransitioning协议
通用代码部分
//.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>


@interface PushTransition : NSObject<UIViewControllerAnimatedTransitioning>


@end


//.m
#import "PushTransition.h"


@interface PushTransition ()


@end


@implementation PushTransition


// This is used for percent driven interactive transitions, as well as for container controllers that have companion animations that might need to
// synchronize with the main animation.
- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext
{
    //返回动画的执行时间
    return 1.0f;
}
// 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];


    //注意注意一定要注意这里。我们就是在这里添加我们所需要的动画效果。将动画效果的代码放在这里就行了。重要的事情要说好几遍


    //如果取消了就设置为NO,反之,设置为YES。如果添加了动画,这句代码在动画结束之后再调用
    [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}实例程序一
实现了一个简单的扇形动画
//.m
#import "PushTransition.h"


@interface PushTransition ()


@property(nonatomic,strong) id<UIViewControllerContextTransitioning>transitionContext;


@end


@implementation PushTransition


// This is used for percent driven interactive transitions, as well as for container controllers that have companion animations that might need to
// synchronize with the main animation.
- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext
{
    return 1.0f;
}
// 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];    
CGRect originRect = CGRectMake(0, 0, 50, 50);


    UIBezierPath *maskStartPath = [UIBezierPath bezierPathWithOvalInRect:originRect];
    UIBezierPath *maskEndPath = [UIBezierPath bezierPathWithOvalInRect:CGRectInset(originRect, -2000, -2000)];


    //创建一个CAShapeLayer来负责展示圆形遮盖
CAShapeLayer *maskLayer = [CAShapeLayer layer];
//    maskLayer.path = maskEndPath.CGPath;//将他的path指定为最终的path,来避免在动画完成后回弹
toVC.view.layer.mask = maskLayer;


    CABasicAnimation *maskAnimation = [CABasicAnimation animationWithKeyPath:@"path"];

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
    NSLog(@"搞定结束");
    [self.transitionContext completeTransition:![self.transitionContext transitionWasCancelled]];
    //去除mask
    [self.transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].view.layer.mask = nil;
    [self.transitionContext viewControllerForKey:UITransitionContextToViewControllerKey].view.layer.mask = nil;
}


@end实例程序二
实现从下方弹出的效果
NSTimeInterval duration = [self transitionDuration:transitionContext];
CGRect screenBounds = [[UIScreen mainScreen]bounds];
CGRect finalFrame = [transitionContext finalFrameForViewController:toVC];
toVC.view.frame = CGRectOffset(finalFrame, 0, screenBounds.size.height);


[UIView animateWithDuration:duration delay:0.0 usingSpringWithDamping:0.6 initialSpringVelocity:0.0 options:UIViewAnimationOptionCurveLinear animations:^{
    toVC.view.frame = finalFrame;
} completion:^(BOOL finished) {
    [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值