2

效果可以像animateTransition方法中的以下代码一样实现:

UIView.animateWithDuration(duration, 
  delay: 0, 
  usingSpringWithDamping: 0.3, 
  initialSpringVelocity: 0.0, 
  options: .CurveLinear, 
  animations: {
    fromVC.view.alpha = 0.5
    toVC.view.frame = finalFrame
  }, 
  completion: {_ -> () in
    fromVC.view.alpha = 1.0
    transitionContext.completeTransition(true)
  })

但是我如何使用重力和碰撞行为(UIGravityBehaviorUICollisionBehavior)来实现它?

一个更普遍的问题可能是“如何使用 来自UIDynamicAnimator定义 之间的转换UIViewControllers?”

4

1 回答 1

4

您可以在 dasdom 发布的具有 UIDynamic 行为的自定义视图控制器转换后找到解决方案

和斯威夫特代码:

func transitionDuration(transitionContext: UIViewControllerContextTransitioning!) -> NSTimeInterval {
  return 1.0
}

func animateTransition(transitionContext: UIViewControllerContextTransitioning!) {

  // 1. Prepare for the required components
  let toVC = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)
  let finalFrame = transitionContext.finalFrameForViewController(toVC)
  let containerView = transitionContext.containerView()
  let screenBounds = UIScreen.mainScreen().bounds

  // 2. Make toVC at the top of the screen
  toVC.view.frame = CGRectOffset(finalFrame, 0, -1.0 * CGRectGetHeight(screenBounds))
  containerView.addSubview(toVC.view)

  // 3. Set the dynamic animators used by the view controller presentation
  var animator: UIDynamicAnimator? = UIDynamicAnimator(referenceView: containerView)
  let gravity = UIGravityBehavior(items: [toVC.view])
  gravity.magnitude = 10

  let collision = UICollisionBehavior(items: [toVC.view])
  collision.addBoundaryWithIdentifier("GravityBoundary",
    fromPoint: CGPoint(x: 0, y: screenBounds.height),
    toPoint: CGPoint(x: screenBounds.width, y: screenBounds.height))

  let animatorItem = UIDynamicItemBehavior(items: [toVC.view])
  animatorItem.elasticity = 0.5

  animator!.addBehavior(gravity)
  animator!.addBehavior(collision)
  animator!.addBehavior(animatorItem)

  // 4. Complete the transition after the time of the duration
  let nsecs = transitionDuration(transitionContext) * Double(NSEC_PER_SEC)
  let delay = dispatch_time(DISPATCH_TIME_NOW, Int64(nsecs))

  dispatch_after(delay, dispatch_get_main_queue()) {
    animator = nil
    transitionContext.completeTransition(true)
  }
}

比使用animateWithDuration:delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completion:方法复杂一点。

编辑:修复了 'transitionDuration' ≤1 时的错误

于 2014-07-12T05:04:08.450 回答