简体   繁体   English

iOS Swift - 如何使用 CABasicAnimation 和 CATransform3DRotate 进行 360 度翻转 animation 与“m34”变换?

[英]iOS Swift - How to do 360 degree flip animation using CABasicAnimation and CATransform3DRotate with "m34" transform?

Despite all my best efforts, I can't figure out how to do a full cycle rotation animation of a UIView using CATransform3DRotate from left to right.尽管我尽了最大的努力,但我无法弄清楚如何使用 CATransform3DRotate 从左到右进行 UIView 的全周期旋转 animation 。 Kindly note that I can already rotate it 360 degree with CABasicAnimation, but without CATransform3DRotate.请注意,我已经可以使用 CABasicAnimation 将其旋转 360 度,但没有 CATransform3DRotate。 However, I want to use .m34 transform for perspective depth.但是,我想使用.m34变换来获得透视深度。 Solutions involving UIView.animate/transitions are not helpful in what I am trying to accomplish.涉及 UIView.animate/transitions 的解决方案对我想要完成的工作没有帮助。 Any help is much appreciated.任何帮助深表感谢。

Edit: I searched far and wide in Stackoverflow and other places, but didn't find anything that describes how to do 360 rotation with CATransform3DRotate.编辑:我在 Stackoverflow 和其他地方进行了广泛搜索,但没有找到任何描述如何使用 CATransform3DRotate 进行 360 度旋转的内容。 Calling top guns out there for help as this is a question that does not seem to have been answered before.在那里寻求帮助,因为这是一个以前似乎没有回答过的问题。 Thanks!谢谢!

Here is the code that rotates UIView 180 degree.这是将 UIView 旋转 180 度的代码。

var transform = CATransform3DIdentity
transform.m34 = 1.0 / -200.0

let animation = CABasicAnimation(keyPath: "transform")
animation.toValue = CATransform3DRotate(transform, CGFloat( Double.pi), 0, 1, 0)
animation.duration = 0.8
animation.beginTime = 0.0
animation.fillMode = .forwards
animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
cardView.layer.add(animation, forKey: "360flip")

在此处输入图像描述

Added two lines before your last cardView.layer.add(animation…) line:在最后一个 cardView.layer.add(animation...) 行之前添加了两行:

    animation.isCumulative = true
    animation.repeatCount = 2

Don't ask how long it took me to figure this out… It's 2am here now, so that'll give you a clue;)不要问我花了多长时间才弄清楚这个……现在是凌晨 2 点,所以这会给你一个线索;)

Cheers.干杯。

PS Note - because you're repeating the animation you can't use .easeInEaseOut or you'll get a pause at 180º so you'll see I also changed that to linear. PS注意 - 因为你重复 animation 你不能使用.easeInEaseOut否则你会在 180º 处暂停,所以你会看到我也将它更改为线性。

Your current code is replacing the entire transform of the animating layer, meaning you can't apply the perspective transform to it.您当前的代码正在替换动画层的整个变换,这意味着您不能对其应用透视变换。 You also have issues with the end state being mathematically identical to the beginning state, and to cope with this you're trying to chain animations together, and using fill modes, which makes the whole thing more complicated.您还遇到了结尾 state 在数学上与开头 state 相同的问题,为了解决这个问题,您尝试将动画链接在一起,并使用填充模式,这使整个事情变得更加复杂。

First, let's deal with the transform.首先,让我们处理转换。 To get the perspective you want to set the .m34 of the layer's transform, which you're already doing:要获得您想要设置图层变换的.m34的透视图,您已经在执行以下操作:

var perspective = CATransform3DIdentity
perspective.m34 = 1 / -200
cardView.layer.transform = perspective

Next, to only touch the rotation of the layer's transform, you can use a more precise key path than transform :接下来,要仅触摸图层变换的旋转,您可以使用比transform更精确的关键路径:

let rotate = CABasicAnimation(keyPath: "transform.rotation.y")
rotate.fromValue = 0

This will leave the rest of the layer's transform intact.这将使层变换的 rest 保持不变。

Finally, how to force the animation engine to notice a difference when the end of the animation is identical to the start?最后,当 animation 的结尾与开头相同时,如何强制 animation 引擎注意到差异? Use byValue :使用byValue

rotate.byValue = CGFloat.pi * 2

This forces the layer to take the long way round to 360 degrees, instead of the lazy shortcut of staying exactly where it is.这会迫使图层绕远至 360 度,而不是停留在原来的位置的懒惰捷径。

The final, complete code is:最终的完整代码是:

var perspective = CATransform3DIdentity
perspective.m34 = 1 / -200
cardView.layer.transform = perspective
let rotate = CABasicAnimation(keyPath: "transform.rotation.y")
rotate.fromValue = 0
rotate.byValue = CGFloat.pi * 2
rotate.duration = 2
cardView.layer.add(rotate, forKey: nil)

Giving this result:给出这个结果:

带透视的 360 度旋转标签

In short, you need two sets of animations.简而言之,你需要两组动画。

Checkout my previous answer https://stackoverflow.com/a/24990978/945906查看我之前的答案https://stackoverflow.com/a/24990978/945906

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM