自定义转场动画 present /dismiss

自定义转场

一.遵循UIViewControllerTransitioningDelegate协议

@interface ViewController ()

二.点击 cell present 到新的控制器

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    NEDetailTableViewController *detailViewC = [[NEDetailTableViewController alloc]init];
    //1
    detailViewC.modalPresentationStyle = UIModalPresentationCustom;
    //2
    detailViewC.transitioningDelegate = self;
    //3
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self presentViewController:detailViewC animated:YES completion:nil];
    });
}

1.设置新控制器的modalPresentationStyleCustom
2.设置transitioningDelegate为自身
3.在主线程present 到新的控制器

三.在执行 present 后会来执行UIViewControllerTransitioningDelegate的代理方法
在代理方法中需要返回一个遵循UIViewControllerAnimatedTransitioning协议的对象

present

//MARK: - UIViewControllerTransitioningDelegate
- (nullable id )animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source{
       
    return transition;
}

dismiss

- (nullable id )animationControllerForDismissedController:(UIViewController *)dismissed{

    return transition;
}

自定义UIViewControllerAnimatedTransitioning NETransition

//  NETransition.h
#import 
@interface NETransition : NSObject
@property (nonatomic, assign) BOOL present;

//  NETransition.m
//返回动画时间
- (NSTimeInterval)transitionDuration:(nullable id )transitionContext{
    return 1.0;
}

//判断是 present /dismiss 执行相对应的动画

- (void)animateTransition:(id )transitionContext
{
    if (self.present) {//present
        [self presentAnimateTransition:transitionContext];
    }else{//dismiss
        [self dismissAnimateTransition:transitionContext];
    }
}
- (void)presentAnimateTransition:(id )transitionContext{
    
    //toViewController:即B视图控制器
    NEDetailTableViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    //toView:B视图控制器的view
    UITableView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
    //containView:可以理解为它管理着所有做转场动画的视图,必须将toView加入到其中
    UIView *containView = [transitionContext containerView];

    NSTimeInterval duration = [self transitionDuration:transitionContext];
    NSLog(@"%f",duration);
   
//以下为相关动画代码 不用看
    if (containView != nil && toView != nil && toViewController != nil) {
        
        toView.frame = [transitionContext finalFrameForViewController:toViewController];
        [containView addSubview:toView];
        
        UIView *midView = [[UIView alloc]initWithFrame:CGRectMake(0, CGRectGetMaxY(self.rect), self.rect.size.width, toView.bounds.size.height - CGRectGetMaxY(self.rect))];
        midView.backgroundColor = [UIColor whiteColor];
        [containView addSubview:midView];
        UIView *bottomView = [[UIView alloc]initWithFrame:CGRectMake(0, toView.bounds.size.height, self.rect.size.width, toView.bounds.size.height- 2*self.rect.size.height)];
        bottomView.backgroundColor = [UIColor orangeColor];
        [containView addSubview:bottomView];
        [containView insertSubview:self.topView atIndex:999];
        self.midView = midView;
        self.botView = bottomView;
        toViewController.bottomView = bottomView;
        [UIView animateWithDuration:0.8 delay:0 options:UIViewAnimationOptionLayoutSubviews animations:^{
            self.topView.frame = CGRectMake(0, 0, self.rect.size.width, self.rect.size.height);
            midView.frame = CGRectMake(0, self.rect.size.height, self.rect.size.width, self.rect.size.height);
            bottomView.frame = CGRectMake(0, CGRectGetMaxY(midView.frame), self.rect.size.width, toView.bounds.size.height- 2*self.rect.size.height);
        } completion:^(BOOL finished) {
            toView.tableHeaderView = self.topView;
          //通知动画结束
            [transitionContext completeTransition:finished];
        }];
    }
}
- (void)dismissAnimateTransition:(id )transitionContext{
    
    //toViewController:即B视图控制器
    ViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    //toView:B视图控制器的view
    UITableView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
    //containView:可以理解为它管理着所有做转场动画的视图,必须将toView加入到其中
    UIView *containView = [transitionContext containerView];

    [UIView animateWithDuration:1.2 delay:0 options:UIViewAnimationOptionLayoutSubviews animations:^{
    
        self.midView.frame = self.rect;
        self.botView.frame = self.rect;
        self.topView.frame = self.rect;

        self.midView.alpha = 0;
        self.botView.alpha = 0;

        
    } completion:^(BOOL finished) {
        [transitionContext completeTransition:finished];

    }];
}

你可能感兴趣的:(自定义转场动画 present /dismiss)