ios - 如何使自定义过渡表现得像重力下落一样?

标签 ios swift uikit-dynamics custom-transition

该效果可以在 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 之间的转换?”

最佳答案

您可以在帖子 Custom view controller transitions with UIDynamic behaviors下找到解决方案 作者: dasdom

以及 Swift 代码:

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 时的错误

关于ios - 如何使自定义过渡表现得像重力下落一样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24708035/

相关文章:

iOS:UIDynamics 推送行为

ios - 如何在 Phonegap iOS 中更改键盘

ios - Upnpx LastChangeParser

ios - 如何存储任意时间

swift - 无法使用 animator() [ OSX ] 为 Swift 自定义属性设置动画

swift - 如何在部署在 Windows Server 上的 Jenkins 上运行 Swift 单元测试

ios - 在代码中创建 JTAppleCalendarView

ios - 类型 'UIGestureRecognizer' 的值没有成员 'numberOfTapsRequired' 为什么会出现此错误?

ios7 - UIDynamics 和设备旋转

ios - UIDynamicAnimator 摇动 Spring 效果