我正在尝试复制此动画以关闭视图控制器(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?
感谢
答案 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之前传递时间。这也假设您使用的是线性曲线。对于任何其他类型的曲线,您必须根据时间估计起始速度是什么并进行调整。