2017-08-11 71 views
4

我正在玩定制和交互式视图控制器转换,使用UIPercentDrivenInteractiveTransition。我正在构建一个以模态方式呈现卡片(其他视图控制器)的应用程序。我制作了与UIViewControllerAnimatedTransitioning一样的自定义转换,它将卡片视图控制器动画化得非常像标准模型演示风格。交互式转换不是线性的

func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { 
    {...} 
    let fullScreenFrame = transitionContext.finalFrame(for: cardVC) 
    let offsetFrame = cardVC.view.frame.offsetBy(dx: 0, dy: cardVC.view.frame.height) 
    let finalFrame = presenting ? fullScreenFrame : offsetFrame 
    cardVC.view.frame = presenting ? offsetFrame : fullScreenFrame 
    containerView.addSubview(cardVC.view) 

    UIView.animateKeyframes(
     withDuration: transitionDuration(using: transitionContext), 
     delay: 0, 
     options: UIViewKeyframeAnimationOptions.calculationModeLinear, 
     animations: { 
      UIView.addKeyframe(
       withRelativeStartTime: 0, 
       relativeDuration: 1, 
       animations: { [weak self] in 
        guard let strongSelf = self else { return } 
        backgroundView.alpha = strongSelf.presenting ? 1 : 0 
      }) 

      UIView.addKeyframe(
       withRelativeStartTime: 0, 
       relativeDuration: 1, 
       animations: { 
        cardVC.view.frame = finalFrame 
      }) 
    }, completion: { finished in 
     backgroundView.removeFromSuperview() 
     gradientView.alpha = 1 
     transitionContext.completeTransition(!transitionContext.transitionWasCancelled) 
    }) 
} 

然后我用一个平底锅手势识别交互驱动驳回动画:

func handleGesture(_ gestureRecognizer: UIScreenEdgePanGestureRecognizer) { 
     let translation = gestureRecognizer.translation(in: gestureRecognizer.view) 
     var progress = (translation.y/(UIScreen.main.bounds.height - 70)) 
     progress = CGFloat(fminf(fmaxf(Float(progress), 0.0), 1.0)) 

     switch gestureRecognizer.state { 
     case .began: 
      interactionInProgress = true 
      viewController.dismiss(animated: true, completion: nil) 

     case .changed: 
      shouldCompleteTransition = progress > 0.35 
      update(progress) 

     case .cancelled: 
      interactionInProgress = false 
      cancel() 

     case .ended: 
      interactionInProgress = false 
      if !shouldCompleteTransition { 
       cancel() 
      } else { 
       finish() 
      } 

     default: 
      print("Unsupported") 
     } 
    } 

当我通过拖动下来驳回呈现视图控制器,它似乎并没有与直线运动手势。看起来交互控制器使用一些easyInEaseOut函数。也许可以设置UIPercentDrivenInteractiveTransitiontimingCurve使转换线性运行。这是可能的,还是我错了?

回答

0

你自己已经给动画一个默认的缓解 - 放松时间曲线,通过在UIView.animateKeyframes的调用中不设置时间曲线来改变任何不同的时间曲线。即使在交互期间也是如此。

注意,设置动画的optionsUIViewKeyframeAnimationOptions.calculationModeLinear变化的时序曲线(如果那是你的想法,你在这里完成)。将线性时序曲线添加到线性计算模式关键帧动画的方式如下所示:

var opts : UIViewKeyframeAnimationOptions = .calculationModeLinear 
let opt2 : UIViewAnimationOptions = .curveLinear 
opts.insert(UIViewKeyframeAnimationOptions(rawValue:opt2.rawValue)) 
// and now use `opts` as your `options`