美文网首页
13.自定义过渡效果

13.自定义过渡效果

作者: LucXion | 来源:发表于2021-12-10 15:40 被阅读0次

    主要分为 自定义视图控制器过渡(时间的函数) 和 交互式视图控制器过渡(手势)。

    所有的过渡,都会创建一个过渡协调器

    将UICollectionViewController集合视图控制器的useLayoutToLayoutNavigationTransitions属性设置为YES,在将集合视图推入导航控制器之前,推入过渡会使用 setCollectionViewLayout:animated: 来完成集合视图布局的变化。

    iOS 7中可以 取消交互式导航控制器过渡,那么要注意可能出现的问题,第一个控制器的ViewWillDisappear,但不会调用ViewDidAppear和ViewDidDisappear。第二个控制器的ViewWillAppear会调用,但ViewDidAppear不会被调用。无论过渡成功或失败都可以通过notifyWhenInteractionChanges收到通知

    自定义视图控制器过渡

    // 给跳转的控制器的过渡效果设置代理
    dest.transitioningDelegate = self;
    
    // 实现 UIViewControllerTransitioningDelegate 协议方法
    - (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext {
      return 1.0f;
    }
    
    - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
      // 获得将要消失或出现的视图控制器的指针,可以设置透明度、frame的改变等实现一些动画效果
      UIViewController *src = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
      UIViewController *dest = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    }
    
    // 负责返回动画对象
    - (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
      
      return self;
    }
    
    - (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
      
      return self;
    }
    

    交互式过渡动画

    不需要实现animateTransition:方法,而是要实现startInteractiveTransition:方法,这个方法里只能有一个动画块。动画应该基于UIView而不是图层,交互式过渡不支持CATransition或CALayer动画。

    // 一、在需要实现过渡动画的控制器内实现以下协议方法
    - (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext {
      return 1.0f;
    }
    
    // 协议 <UIViewControllerInteractiveTransitioning>
    - (void)startInteractiveTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
      
      UIViewController *src = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
      
      CGPoint centerPoint = src.view.center;
      [UIView animateWithDuration:1.0 animations:^{
        
        src.view.frame = CGRectMake(centerPoint.x, centerPoint.y, 10, 10);
        src.view.center = centerPoint;
      } completion:^(BOOL finished) {
        // 如果取消了过渡,这里要返回 NO,否则会多出一个遮挡视图 UITransitionView
        [transitionContext completeTransition:YES];
      }];
    }
    
    - (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
      
      return self;
    }
    
    - (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
      
      return self;
    }
    
    - (id <UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id <UIViewControllerAnimatedTransitioning>)animator {
      
      return self.animator; // 继承自 UIPercentDrivenInteractiveTransition
    }
    
    - (id <UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id <UIViewControllerAnimatedTransitioning>)animator {
      
      return self.animator; // UIPercentDrivenInteractiveTransition
    }
      // 二、初始化过渡交互动画,并将手势与动画绑定
     self.animator = [[SCTPercentDrivenAnimator alloc] initWithViewController:self];
      UIPinchGestureRecognizer *gr = [[UIPinchGestureRecognizer alloc] initWithTarget:self.animator
                                                                               action:@selector(pinchGestureAction:)];
      
      [self.view addGestureRecognizer:gr];
    
    // 三、过渡动画类的实现
    @interface SCTPercentDrivenAnimator (/*Private Methods*/)
    @property (nonatomic, assign) float startScale;
    @property (weak, nonatomic) UIViewController *controller;
    @end
    
    @implementation SCTPercentDrivenAnimator
    
    -(instancetype) initWithViewController:(UIViewController*) controller {
      if((self = [super init])) {
        self.controller = controller;
      }
      return self;
    }
    
    -(void) pinchGestureAction:(UIPinchGestureRecognizer*) gestureRecognizer {
      
      CGFloat scale = gestureRecognizer.scale;
      if(gestureRecognizer.state == UIGestureRecognizerStateBegan) {
        
        self.startScale = scale;
        [self.controller dismissViewControllerAnimated:YES completion:nil];
      }
      if(gestureRecognizer.state == UIGestureRecognizerStateChanged) {
        
        CGFloat completePercent = 1.0 - (scale/self.startScale);
        [self updateInteractiveTransition:completePercent];
      }
      if(gestureRecognizer.state == UIGestureRecognizerStateEnded) {
        
        if(gestureRecognizer.velocity >= 0)
           [self cancelInteractiveTransition];
        else
          [self finishInteractiveTransition];
      }
      
      if(gestureRecognizer.state == UIGestureRecognizerStateCancelled) {
        
        [self cancelInteractiveTransition];
      }
    }
    @end
      
    

    相关文章

      网友评论

          本文标题:13.自定义过渡效果

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