Ios 图像的快速圆周运动动画
创建一个应用程序,其中图像在按下按钮时移动(重复3次)。该图像目前有一个线性运动,但我需要的是一个循环运动动画 图像应从屏幕左侧开始,向顶部移动,然后向屏幕右侧移动,这样图像有3个停止点。这必须通过循环动画来完成Ios 图像的快速圆周运动动画,ios,swift,image,animation,Ios,Swift,Image,Animation,创建一个应用程序,其中图像在按下按钮时移动(重复3次)。该图像目前有一个线性运动,但我需要的是一个循环运动动画 图像应从屏幕左侧开始,向顶部移动,然后向屏幕右侧移动,这样图像有3个停止点。这必须通过循环动画来完成 enum TimeOfDay: String { case Dimineata = "Dimineata" case Pranz = "Pranz" case Seara = "Seara" } class ViewController: UIViewCont
enum TimeOfDay: String {
case Dimineata = "Dimineata"
case Pranz = "Pranz"
case Seara = "Seara"
}
class ViewController: UIViewController {
@IBOutlet weak var timeOfDayLabel: UILabel!
@IBOutlet weak var sunImage: UIImageView!
var timeOfDay = TimeOfDay.Dimineata
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func didTapNext(_ sender: Any) {
switch timeOfDay {
case .Dimineata:
timeOfDay = .Pranz
sunImage.image = UIImage(named: "LunchSun")
UIView.animate(withDuration: 1) {
self.sunImage.frame = CGRect(x: self.view.center.x-50, y: 120, width: 100, height: 100)
}
case .Pranz:
timeOfDay = .Seara
sunImage.image = UIImage(named: "NightSun")
UIView.animate(withDuration: 1) {
self.sunImage.frame = CGRect(x: self.view.frame.width-50, y: 166, width: 100, height: 100)
}
default:
timeOfDay = .Dimineata
sunImage.image = UIImage(named: "NightSun")
UIView.animate(withDuration: 1) {
self.sunImage.frame = CGRect(x: self.view.frame.origin.x-50, y: 166, width: 100, height: 100)
}
}
timeOfDayLabel.text = timeOfDay.rawValue.uppercased()
}
}
- 创建圆形路径
- 创建一个
CAKeyframeAnimation
- 将
设置为循环路径动画.path
- 将该动画添加到图像视图的层中
- 将图像视图的框架设置为路径中的最后一点
var imageView : UIImageView!
// Adapt these constants to your case
let initialX: CGFloat = 40
let imageViewWidth: CGFloat = 60
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
imageView = UIImageView()
imageView.backgroundColor = .red
imageView.frame = CGRect(x: initialX,
y: view.frame.height / 2.0 - 20,
width: 60,
height: 40)
imageView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(imageView)
}
@IBAction func animate(_ sender: Any) {
//You can customize this path
let circularPath = UIBezierPath(arcCenter: view.center,
radius: view.frame.width / 2 - initialX - imageViewWidth / 2,
startAngle: -.pi,
endAngle: 0,
clockwise: true)
//Create the animation
let animation = CAKeyframeAnimation(keyPath: #keyPath(CALayer.position))
animation.duration = 2 // In seconds
animation.repeatCount = 1 //At maximum it could be MAXFLOAT if you want the animation to seem to loop forever
animation.path = circularPath.cgPath
animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) //Optional
//Add the animation to the layer of the image view
imageView.layer.add(animation, forKey: "myAnimation")
//prevent the imageView from going back to its original coordinates
imageView.frame.origin.x = circularPath.cgPath.currentPoint.x - imageView.frame.width / 2
imageView.frame.origin.y = circularPath.cgPath.currentPoint.y - imageView.frame.height / 2
}
基本上-创建一条路径和相应的动画。就像把太阳放在一个看不见的手臂的末端,像时钟的指针一样旋转手臂一样。谢谢!这最终奏效了,但我有两个问题:1。动画结束后,图像会返回到其原始坐标(我使用的是最后一行代码,您在其中清楚地指定它是为了避免这种情况发生的)2。因此,动画从左侧开始,向上移动(必须停止),然后向右侧移动(也必须停止),创建一个半圆。但是,动画直接从左向右移动。我应该创建单独的动画来实现我的目标,还是以某种方式暂停/恢复动画?上面的代码给出了一个半圆动画。您可以通过调整
startAngle
和endAngle
将其调整为四分之一圆。对于您来说,您必须有三个动画:Dimineata
到Pranz
,Pranz
到Seara
,和Seara
返回Dimineata
如果此答案解决了您的问题,请单击答案旁边的复选标记将其标记为已接受,或/并向上投票。有关更多信息,请参阅