2017-08-11 85 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`