如何在一定程度范围内为UIView的旋转设置动画?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在一定程度范围内为UIView的旋转设置动画?相关的知识,希望对你有一定的参考价值。
在我的应用程序中,我有一个模拟读数表盘的模拟,就像你可能在汽车仪表板或控制面板上找到的那样。运行以下代码片段以获取我的意思的示例:
svg { height: 100vh; }
#dial {
fill: white;
stroke: #CCCCCC;
stroke-dasharray: 405;
transform: rotate(135deg);
transform-origin: center;
}
#pointer {
fill: #FF0000;
animation: 2s infinite alternate dialrotate;
transform-origin: bottom center;
animation-timing-function: ease-in-out;
}
@keyframes dialrotate {
from {
transform: rotate(-135deg);
}
to {
transform: rotate(135deg);
}
}
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200">
<circle id="dial" cx="99.5" cy="100.5" r="86"/>
<polygon id="pointer" points="100.1,25.5 98.2,100 102,100"/>
</svg>
(我在我的应用程序中没有使用SVG - 我只是使用SVG将示例放在一起,因为我主要是一个Web开发人员)
这就是我现在为表盘动画制作动画的方法:
UIView.animate(
withDuration: 0.1,
delay: 0.0,
options: .curveEaseOut,
animations: {
self.dialPointer.transform = CGAffineTransform.init(rotationAngle: radians);
},
completion: nil
)
我想在两个极端(270度)之间设置指针的方向。但我不希望指针在表盘边界外的较短的90度路径上旋转;即这是错误的:
svg { height: 100vh; }
#dial {
fill: white;
stroke: #CCCCCC;
stroke-dasharray: 405;
transform: rotate(135deg);
transform-origin: center;
}
#pointer {
fill: #FF0000;
animation: 2s infinite alternate dialrotate;
transform-origin: bottom center;
animation-timing-function: ease-in-out;
}
@keyframes dialrotate {
from {
transform: rotate(225deg);
}
to {
transform: rotate(135deg);
}
}
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200">
<circle id="dial" cx="99.5" cy="100.5" r="86"/>
<polygon id="pointer" points="100.1,25.5 98.2,100 102,100"/>
</svg>
如何强制UIView旋转长距离旋转,而不是在最短的方向上旋转?
答案
正如您所发现的,默认情况下,UIView动画在插入角度值时采用最短路径。你有几个选择:
- 您可以将动画分解为几个较短的步骤,或者将其设置为关键帧。
- 您可以改为使用CABasicAnimation,并使用累积动画为图层的变换设置动画
游乐场示例:
import PlaygroundSupport
import UIKit
let rect = CGRect(x: 0, y: 0, width: 300, height: 300)
let view = UIView(frame: rect)
let bar = UIView(frame: rect.insetBy(dx: 40, dy: 140))
bar.backgroundColor = .red
view.addSubview(bar)
let animation = CABasicAnimation(keyPath: "transform.rotation.z")
animation.toValue = 1.25 * CGFloat.pi
animation.isCumulative = true
animation.duration = 5
bar.layer.add(animation, forKey: "spin")
bar.layer.transform = CATransform3DMakeRotation(1.25 * CGFloat.pi, 0, 0, 1)
PlaygroundPage.current.liveView = view
另一答案
你可以这样做
UIView.animate(
withDuration: 0.1,
delay: 0.0,
options: .curveEaseOut,
animations: {
if radians > CGFloat.pi {
self.dialPointer.transform = CGAffineTransform.init(rotationAngle: CGFloat.pi);
}
self.dialPointer.transform = CGAffineTransform.init(rotationAngle: radians);
},
completion: nil
)
以上是关于如何在一定程度范围内为UIView的旋转设置动画?的主要内容,如果未能解决你的问题,请参考以下文章