关闭视图控制器自定义动画

时间:2016-03-12 16:47:34

标签: ios iphone swift uiviewanimationtransition

我正在尝试复制此动画以关闭视图控制器(15秒视频):https://www.youtube.com/watch?v=u87thAbT0CQ

这是我的动画到目前为止的样子:https://www.youtube.com/watch?v=A2XmXTVxLdw

这是我的平移手势识别器代码:

 @IBAction func recognizerDragged(sender: AnyObject) {
    let displacement = recognizer.translationInView(view)
    view.center = CGPointMake(view.center.x + displacement.x, view.center.y + displacement.y)
    recognizer.setTranslation(CGPoint.zero, inView: view)
    switch recognizer.state {
    case .Ended:
        UIView.animateWithDuration(0.4, animations: { () -> Void in
            self.view.layer.position = CGPoint(x: self.view.frame.width / 2, y: self.view.frame.height / 2)
        })
    default:
        print("default")
    }

    let velocity = recognizer.velocityInView(self.titleView)
    print(velocity)
    if velocity.y < -1500 {
        up = true
      self.dismissViewControllerAnimated(true, completion: nil)
    }
    if velocity.x > 1500 {
        right = true
        self.dismissViewControllerAnimated(true, completion: nil)
    }
}

在我的视频中可能有点难以注意到,但是用户轻弹的速度以及动画完成的速度有一个小的断开。也就是说,用户可以非常快地翻转但是动画被设置为硬编码的0.3秒。因此,如果用户快速轻弹视图,那么当动画完成时,只要他们的手指抬离视图,动画就会慢下来。

我认为我需要的是一种获取记录在识别器中的速度IBAction的方法,然后将其传递给动画控制器,并根据它计算动画应该花多长时间,以便速度始终如一,它看起来很顺利。我怎么能这样做?

Additioanlly,我有点困惑,因为Apple文档说velocityInView函数以点为单位返回速度,而不是像素。然而,不同的iOS设备每个像素具有不同的点,因此这会使我在将速度传递到动画类之前转换速度变得更加复杂。

任何想法如何将速度传递回动画控制器,以便动画持续时间根据它变化,并使其适用于不同的iPhone?

感谢

1 个答案:

答案 0 :(得分:3)

您尝试复制的视频中可能会看到的是UIDynamics风格的交互,而不是CoreAnimation动画。从velocityInView返回的速度可以直接在UIDynamics中使用,如下所示:

[self.behavior addLinearVelocity:
        [pan velocityInView:pan.view.superview] forItem:pan.view];

我在这里编写了一个用于进行此类视图交互的教程:https://www.smashingmagazine.com/2014/03/ios7-new-dynamic-app-interactions/

要坚持使用UIView动画,您只需要查看框架的底部(也在点中)并计算新时间。这假设您希望帧的底部在动画结束时为0:

  animationTime = CGRectGetMaxY(frame) / velocity

您没有展示如何创建动画控制器,只是保留对它的引用并在调用dismiss之前传递时间。这也假设您使用的是线性曲线。对于任何其他类型的曲线,您必须根据时间估计起始速度是什么并进行调整。