美文网首页
06-自定义转场动画遇到的坑

06-自定义转场动画遇到的坑

作者: 流星大石头 | 来源:发表于2016-05-06 13:22 被阅读381次

    如果你在自定义转场动画的时候不设置modalPresentionStyle或者设置成UIModalPresentationCustom,很有可能在modal完成之后出现底部是黑屏的状况。
    这个时候的解决方案就是:
    [[UIApplication sharedApplication].keyWindow insertSubview:fromView belowSubview:containerView];
    将之前底部可以看见的视图重新添加到视图层次结构中。
    但是如果你把modalPresentionStyle设置为UIModalPresentationCustom,竟然没有出现这个问题。

    坑:


    1.gif

    想要达到的效果:

    1.gif

    解决坑的参考代码:

    #import "ViewController.h"
    
    @interface ViewController ()<UIViewControllerTransitioningDelegate,UIViewControllerAnimatedTransitioning>
    
    @property (nonatomic,strong) UIButton* presentButton;
    @property (nonatomic,strong) UIViewController* modalVC;
    @property (nonatomic,assign) BOOL isPresenting;
    
    @property (nonatomic,strong) UIView* dimingView;
    
    @property (nonatomic,strong) UITapGestureRecognizer* tapGesture;
    
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        self.modalVC = [[UIViewController alloc] init];
        self.modalVC.transitioningDelegate = self;
        self.modalVC.view.backgroundColor = [UIColor redColor];
    //    self.modalVC.modalPresentationStyle = UIModalPresentationCustom;
        self.isPresenting = true;
        
        [self.view addSubview:self.presentButton];
        
        [self layoutPageSubviews];
    
        
    }
    
    #pragma mark - UIViewControllerAnimatedTransitioning
    
    
    - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
        
        //1.获得容器视图
        UIView* containerView = [transitionContext containerView];
        
        //2.获得目标控制器和视图
        UIView* toView = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey].view;
         UIView* fromView = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].view;
        if (self.isPresenting) {
            //present
            
            toView.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width-100, [UIScreen mainScreen].bounds.size.height-300);
            toView.center = CGPointMake(containerView.center.x, -containerView.center.y);
            
            
            //3.创建遮罩视图
            self.dimingView = [[UIView alloc] initWithFrame:self.view.bounds];
            self.dimingView.backgroundColor = [UIColor blackColor];
    //        self.dimingView.alpha = 0.0;
            self.dimingView.layer.opacity = 0.0;
            [self.dimingView addGestureRecognizer:self.tapGesture];
            //4.将要进行动画的视图添加到容器视图中
           
            [containerView addSubview:self.dimingView];
            [containerView addSubview:toView];
            /*
             一定要注意添加顺序,如果toView在dimingView之前添加,dimingView就把toView给覆盖了,这样就无法点击toView了,点击的全部都是dimingView
             */
            
            [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
                
                self.dimingView.layer.opacity = 0.2;
                toView.center = CGPointMake(containerView.center.x, containerView.center.y);
                
            } completion:^(BOOL finished) {
               
                [transitionContext completeTransition:true];
                //如果视图被移除,我们就自己添加上去
                [[UIApplication sharedApplication].keyWindow insertSubview:fromView belowSubview:containerView];
            }];
    
        }
        else {
        
            [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
               
                self.dimingView.alpha = 0.0;
                fromView.center =  CGPointMake(containerView.center.x, containerView.center.y+[UIScreen mainScreen].bounds.size.height);
                
            } completion:^(BOOL finished) {
                
                [transitionContext completeTransition:true];
                
            }];
            
        }
        
        
        
    }
    
    
    - (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext {
    
        return 0.5;
    }
    
    
    #pragma mark - UIViewControllerTransitioningDelegate代理方法
    
    - (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
    
        self.isPresenting = true;
        
        return self;
    }
    
    - (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
    
        self.isPresenting = false;
        
        return  self;
    }
    
    
    #pragma mark - 响应事件
    
    //点击遮罩
    - (void) exit:(UITapGestureRecognizer*) tap {
    
        [self.modalVC dismissViewControllerAnimated:true completion:^{
            
        }];
    }
    //点击测试
    - (void) modal:(UIButton*) sender {
        
        [self presentViewController:self.modalVC animated:true completion:^{
            
        }];
    }
    
    
    #pragma mark - 设置约束
    - (void) layoutPageSubviews{
        
        //代码自动布局要先机制掉autoResizing
        self.presentButton.translatesAutoresizingMaskIntoConstraints = NO;
        
        [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.presentButton attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0]];
        [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.presentButton attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1.0f constant:0]];
        [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.presentButton attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0 constant:100]];
        [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.presentButton attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0 constant:100]];
        
    }
    
    
    #pragma mark - 懒加载
    
    - (UITapGestureRecognizer *)tapGesture{
    
        if (_tapGesture==nil) {
            
            _tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(exit:)];
        }
        
        return _tapGesture;
    }
    
    - (UIButton *)presentButton{
    
        if (_presentButton==nil) {
            
            _presentButton = [[UIButton alloc] init];
            [_presentButton setTitle:@"测试" forState:UIControlStateNormal];
            [_presentButton setBackgroundColor:[UIColor orangeColor]];
            [_presentButton addTarget:self action:@selector(modal:) forControlEvents:UIControlEventTouchDown];
        }
        
        return _presentButton;
    }
    
    
    

    相关文章

      网友评论

          本文标题:06-自定义转场动画遇到的坑

          本文链接:https://www.haomeiwen.com/subject/mzkjrttx.html