Swift iOS多个连续多个动画与相同的UIView?

时间:2017-01-23 00:58:19

标签: ios swift animation uiimageview

所以这就是我现在所处的位置。我仍然无法让它工作,我尝试了很多变化。这是我单个动画的原始代码。

import UIKit

class ViewController: UIViewController {

@IBOutlet weak var imageView: UIImageView!

override func viewDidLoad() {
    super.viewDidLoad()

    var images = [UIImage]()
    var images2 = [UIImage]()

    images += [#imageLiteral(resourceName: "circle1"), #imageLiteral(resourceName: "circle2"), #imageLiteral(resourceName: "circle3"), #imageLiteral(resourceName: "circle4")]
    images2 += [#imageLiteral(resourceName: "circle4"), #imageLiteral(resourceName: "circle3"), #imageLiteral(resourceName: "circle2"), #imageLiteral(resourceName: "circle1")]

    imageView.animationImages = images

    imageView.animationDuration = 4.0

    imageView.animationRepeatCount = 2

    imageView.startAnimating()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}
}

我可以使用我为持续时间和计数设置的属性为第一个图像数组设置动画。但是,我只是不明白我是怎么写这个来添加第二组图像后立即动画。我知道我需要以某种方式使用它:

 UIView.animate(withDuration: 4.0, animations: {
     //animation 1
 }, completion: { (value: Bool) in
     UIView.animate(withDuration: 6.0, animations: {
         //animation 2
     })
 })

有人可以告诉我如何使用相同的imageView对象显示这两个动画,我的当前图像数组会写这个吗?我希望我的第一个动画(图像)的持续时间为4秒,我的第二个动画(images2)在第一个动画之后立即持续6秒。我无法在动画参数中弄清楚我需要什么。

3 个答案:

答案 0 :(得分:2)

我知道你说这对你没用,但如果你只是想要一个接一个地执行动画,我相信这确实是最好的选择。

你应该可以这样做:

let imageView = UIImageView()
UIView.animate(withDuration: 0.5, animations: {
    //animation 1
}, completion: { (value: Bool) in
    UIView.animate(withDuration: 1.0, animations: {
        //animation 2
    })
})

这会直接在另一个动画之后执行一个动画,持续时间更长。当然你还需要定义动画是什么,但我希望这会有所帮助。

答案 1 :(得分:1)

我认为错误是你在这里混合两件事:

  • UIView.animate - >动画控件和属性
  • UIImageView.startAnimating - >在UIImageView中启动图像循环

但是他们不是这样做的,他们是非常独立的。但UIView动画通常用于其他用例。只有一件事是它们可能具有与UIImageView动画相同的持续时间,但您不必设置UIImageView的持续时间。也许当您将图像视图的动画持续时间设置为UIView动画的持续时间时,它可以在相同的时间范围内完成。

myImageView.animationDuration = 2;

和第二个循环

myImageView.animationDuration = 4;

其他解决方案

你需要知道图像循环何时完成。但没有事件(我没有发现任何事件)

StackOverflow上有一些解决方案:

1 performSelector afterDelay

设置计时器在持续时间结束后触发。为此,您还需要为图像视图添加动画持续时间:

myImageView.animationDuration = 0.7;
来自此处的

解决方案:how to do imageView.startAnimating() with completion in swift?

  

按下按钮时,您可以调用延迟功能

self.performSelector("afterAnimation", withObject: nil, afterDelay: imageView1.animationDuration)
     

然后停止动画并将imageArray的最后一个图像添加到afterAnimation函数中的imageView

func afterAnimation() {
    imageView1.stopAnimating()
    imageView1.image = imageArray.last
}

2计时器

这与performSelector afterDelay类似,但与NSTimer类似。

您在UIImageView startAnimating: How do you get it to stop on the last image in the series?找到了说明:

  

1)设置动画图像属性并启动动画(如   您在问题中的代码)

     

2)安排NSTimer在“动画片制作”中进行演绎'秒时间

     

3)当计时器熄灭时,[...]

添加到第3点:然后开始下一个动画

3 CATransaction

来自此处的

解决方案:Cocoa animationImages finish detection(您需要将其转换为swift 3语法,但它可以作为起点

  

很老的问题,但我现在需要修复,这对我有用:

[CATransaction begin];
[CATransaction setCompletionBlock:^{
    DLog(@"Animation did finish.");
}];

UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.window.bounds];
imageView.animationDuration = 0.3 * 4.0;
imageView.animationImages = @[[UIImage AHZImageNamed:@"Default2"],
                              [UIImage AHZImageNamed:@"Default3"],
                              [UIImage AHZImageNamed:@"Default4"],
                              [UIImage AHZImageNamed:@"Default5"]];
imageView.animationRepeatCount = 1;
[self.window addSubview:imageView];

[imageView startAnimating];

[CATransaction commit];

4 Offtopic:手动执行图像动画

这有点偏离主题,因为在这里他们手动完成图像动画。对于您的用例,您只需更改索引中的图像可见的逻辑。向前计数直到最后一张图像,然后向后计数到第一张图像。然后停止循环。不是很好的解决方案,但在此解决方案中添加了图像过渡动画:

此处的解决方案:Adding Image Transition Animation in Swift

class ViewController: UIViewController {
        @IBOutlet weak var imageView: UIImageView!

        let images = [
                UIImage(named: "brooklyn-bridge.jpg")!,
                UIImage(named: "grand-central-terminal.jpg")!,
                UIImage(named: "new-york-city.jpg"),
                UIImage(named: "one-world-trade-center.jpg")!,
                UIImage(named: "rain.jpg")!,
                UIImage(named: "wall-street.jpg")!]
        var index = 0
        let animationDuration: NSTimeInterval = 0.25
        let switchingInterval: NSTimeInterval = 3

        override func viewDidLoad() {
                super.viewDidLoad()

                imageView.image = images[index++]
                animateImageView()
        }

        func animateImageView() {
                CATransaction.begin()

                CATransaction.setAnimationDuration(animationDuration)
                CATransaction.setCompletionBlock {
                        let delay = dispatch_time(DISPATCH_TIME_NOW, Int64(self.switchingInterval * NSTimeInterval(NSEC_PER_SEC)))
                        dispatch_after(delay, dispatch_get_main_queue()) {
                                self.animateImageView()
                        }
                }

                let transition = CATransition()
                transition.type = kCATransitionFade
                /*
                transition.type = kCATransitionPush
                transition.subtype = kCATransitionFromRight
                */
                imageView.layer.addAnimation(transition, forKey: kCATransition)
                imageView.image = images[index]

                CATransaction.commit()

                index = index < images.count - 1 ? index + 1 : 0
        }
}
     

将其实现为自定义图像视图会更好。

答案 2 :(得分:1)

我不确定这是否是最好的方法,但我找到了解决问题的方法。如果有更好的方法,请提供反馈。我可以使用以下方法连续在单个UIImageView中完成多个动画:self.perform(#selector(ViewController.afterAnimation), with: nil, afterDelay: 4.0)

这会调用afterAnimation函数:

 func afterAnimation() {
         imageView.stopAnimating()
         imageView.animationImages = images2
         imageView.animationDuration = 6.0
         imageView.animationRepeatCount = 1
         imageView.startAnimating()
     }

我需要动画每一段特定的时间,并能够将它们中的许多链接在一起。它解决了我的问题。