如何为UIImageView中的图像变化设置动画?


198

我有UIImageView一张图片。现在,我有了一个全新的图像(图形文件),并希望在此显示它UIImageView。如果我刚设定

myImageView.image = newImage;

新图像立即可见。无法制作动画。

我希望它很好地淡入新图像。我认为也许有比仅UIImageView在此基础上创建一个新动画并与动画混合更好的解决方案了?


Answers:


260

我不确定是否可以使用淡入淡出效果对UIViews进行动画处理,因为似乎所有受支持的视图过渡都是在UIViewAnimationTransition枚举中定义的。使用CoreAnimation可以实现淡入淡出效果。此方法的示例示例:

#import <QuartzCore/QuartzCore.h>
...
imageView.image = [UIImage imageNamed:(i % 2) ? @"3.jpg" : @"4.jpg"];

CATransition *transition = [CATransition animation];
transition.duration = 1.0f;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionFade;

[imageView.layer addAnimation:transition forKey:nil];

2
从一个图像转到另一个图像时,您的代码可以完美地工作。您是否知道如何使其与UIImageView(animationImages属性)中的图像自动动画一起使用?
CedricSoubrie 2011年

您可以尝试将CAKeyFrameAnimation用于图层的content属性,但不确定效果是否相同。或设置动画委托,并在委托回调函数中在上一个动画完成时开始动画显示下一个图像。
弗拉基米尔

2
这绝对比手动交叉淡化单独的图像视图更简单。谢谢!
凯夫拉尔

好吧..如果imageviews框架发生变化,那么它将保持在原位置。
hfossli 2012年

@Fossli,您是说动画期间帧发生变化时?那是一个不同的问题
Vladimir

368
[UIView transitionWithView:textFieldimageView
                  duration:0.2f
                   options:UIViewAnimationOptionTransitionCrossDissolve
                animations:^{
                    imageView.image = newImage;
                } completion:nil];

是另一种可能性


1
简单,并在图像之间打开了一系列其他动画效果。
所以在

1
@hfossli提到了有关帧更改的相同问题。如果在此期间更改布局,动画将变得缓慢。
Geva

1
这是最好的解决方案,因为它可以与其他动画组合。
凯琳2015年

160

用迈克尔·斯科特(Michael Scott)的话说,保持简单愚蠢。这是在Swift 3Swift 4中执行此操作的简单方法:

UIView.transition(with: imageView,
                  duration: 0.75,
                  options: .transitionCrossDissolve,
                  animations: { self.imageView.image = toImage },
                  completion: nil)

3
奇迹般有效。谢谢!
罗伯托

1
乌乌太好了!这么长的时间都不知道:)
萨比兰郡

1
这将更改为1张图像。如果我有一系列图像并希望以过渡动画一张一张地显示怎么办?
Ammar Mujeeb

1
您可以使用完成块过渡到下一个。
齐亚

41

这是Swift中的一个示例,该示例将首先交叉溶解新图像,然后添加有弹性的动画:

var selected: Bool {
  willSet(selected) {
    let expandTransform:CGAffineTransform = CGAffineTransformMakeScale(1.15, 1.15);
    if (!self.selected && selected) {
      UIView.transitionWithView(self.imageView,
        duration:0.1,
        options: UIViewAnimationOptions.TransitionCrossDissolve,
        animations: {
          self.imageView.image = SNStockCellSelectionAccessoryViewImage(selected)
          self.imageView.transform = expandTransform
        },
        completion: {(finished: Bool) in
          UIView.animateWithDuration(0.4,
            delay:0.0,
            usingSpringWithDamping:0.40,
            initialSpringVelocity:0.2,
            options:UIViewAnimationOptions.CurveEaseOut,
            animations: {
              self.imageView.transform = CGAffineTransformInvert(expandTransform)
            }, completion:nil)
      })
    }
  }
}

var imageView:UIImageView

如果imageView已将if 作为子视图正确添加到视图中,则在selected = false到之间切换selected = true时应将图像换成有弹性的动画。SNStockCellSelectionAccessoryViewImage只会根据当前选择状态返回不同的图像,如下所示:

private let SNStockCellSelectionAccessoryViewPlusIconSelected:UIImage = UIImage(named:"PlusIconSelected")!
private let SNStockCellSelectionAccessoryViewPlusIcon:UIImage = UIImage(named:"PlusIcon")!

private func SNStockCellSelectionAccessoryViewImage(selected:Bool) -> UIImage {
  return selected ? SNStockCellSelectionAccessoryViewPlusIconSelected : SNStockCellSelectionAccessoryViewPlusIcon
}

下面的GIF示例放慢了一点,实际的动画发生得更快了:

                                       UIImageView反弹动画Gif


16

码:

var fadeAnim:CABasicAnimation = CABasicAnimation(keyPath: "contents");

fadeAnim.fromValue = firstImage;
fadeAnim.toValue   = secondImage;
fadeAnim.duration  = 0.8;         //smoothest value

imageView.layer.addAnimation(fadeAnim, forKey: "contents");

imageView.image = secondImage;

例:

来自代码的UIImageView示例

有趣,更详细的解决方案:(在水龙头上切换

    let fadeAnim:CABasicAnimation = CABasicAnimation(keyPath: "contents");

    switch imageView.image {
        case firstImage?:
            fadeAnim.fromValue = firstImage;
            fadeAnim.toValue   = secondImage;
            imageView.image    = secondImage;
        default:
            fadeAnim.fromValue = secondImage;
            fadeAnim.toValue   = firstImage;
            imageView.image    = firstImage;
    }

    fadeAnim.duration = 0.8;

    imageView.layer.addAnimation(fadeAnim, forKey: "contents");


8

使用Swift 3

extension UIImageView{   
 var imageWithFade:UIImage?{
        get{
            return self.image
        }
        set{
            UIView.transition(with: self,
                              duration: 0.5, options: .transitionCrossDissolve, animations: {
                                self.image = newValue
            }, completion: nil)
        }
    }
}

用法:

myImageView.imageWithFade = myImage

6

为什么不试试这个。

NSArray *animationFrames = [NSArray arrayWithObjects:
  [UIImage imageWithName:@"image1.png"],
  [UIImage imageWithName:@"image2.png"], 
  nil];

UIImageView *animatedImageView = [[UIImageView alloc] init];
animatedImageView.animationImages = animationsFrame;
[animatedImageView setAnimationRepeatCount:1];
[animatedImageView startAnimating];

快速版本:

let animationsFrames = [UIImage(named: "image1.png"), UIImage(named: "image2.png")]
let animatedImageView = UIImageView()
animatedImageView.animationImages = animationsFrames
animatedImageView.animationRepeatCount = 1
animatedImageView.startAnimating()

这将UIImageView设置为永远重复切换...作者只是在要求更改:(
J-Dizzle 2015年

setAnimationRepeatCount
威廉·胡

SetAnimationRepeatCount不会更改任何内容。它永远不会停止
Yucel Bayram 2015年

5
CABasicAnimation* fadeAnim = [CABasicAnimation animationWithKeyPath:@"contents"];
fadeAnim.fromValue = (__bridge id)imageView.image.CGImage;
fadeAnim.toValue = (__bridge id)[UIImage imageNamed:@"newImage.png"].CGImage;
fadeAnim.duration = 2.0;
[imageView.layer addAnimation:fadeAnim forKey:@"contents"];
imageView.layer.contents = (__bridge id)[UIImage imageNamed:@"newImage.png"].CGImage;

3

这里有几种不同的方法:回忆起UIAnimations,这听起来像是您的挑战。

编辑:我太懒了:)

在帖子中,我指的是这种方法:

[newView setFrame:CGRectMake( 0.0f, 480.0f, 320.0f, 480.0f)]; //notice this is OFF screen!
[UIView beginAnimations:@"animateTableView" context:nil];
[UIView setAnimationDuration:0.4];
[newView setFrame:CGRectMake( 0.0f, 0.0f, 320.0f, 480.0f)]; //notice this is ON screen!
[UIView commitAnimations];

但是,不对框架进行动画处理,而是对Alpha进行动画处理:

[newView setAlpha:0.0]; // set it to zero so it is all gone.
[UIView beginAnimations:@"animateTableView" context:nil];
[UIView setAnimationDuration:0.4];
[newView setAlpha:0.5]; //this will change the newView alpha from its previous zero value to 0.5f
[UIView commitAnimations];

2

从iOS 5开始,此操作要容易得多:

[newView setAlpha:0.0];
[UIView animateWithDuration:0.4 animations:^{
    [newView setAlpha:0.5];
}];

4
这没有帮助原始问题,那就是您已经显示了图像,并且想淡入淡出到新图像...
Kendall Helmstetter Gelner 2012年

4
对..这个答案不能解决问题。问题不是在图像视图中如何淡入淡出,而是如何从旧图像淡入到新图像。动画块是在iOS的4推出
巴斯蒂安

2

Swift 4这太棒了

  self.imgViewPreview.transform = CGAffineTransform(scaleX: 0, y: 0)
          UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0, options: .curveEaseOut, animations: {
              self.imgViewPreview.image = newImage
              self.imgViewPreview.transform = .identity
          }, completion: nil)

1

弗拉基米尔的答案是完美的,但像我这样的人正在寻找快速解决方案

此解决方案适用于Swift 4.2版本

var i = 0
    func animation(){
        let name = (i % 2 == 0) ? "1.png" : "2.png"
        myImageView.image = UIImage.init(named: name)
        let transition: CATransition = CATransition.init()
        transition.duration = 1.0
        transition.timingFunction = CAMediaTimingFunction.init(name: .easeInEaseOut)
        transition.type = .fade
        myImageView.layer.add(transition, forKey: nil)
        i += 1
    }

您可以在任何地方调用此方法。它将通过动画将图像更改为下一个图像。

对于Swift版本4.0使用波纹管解决方案

var i = 0
    func animationVersion4(){
        let name = (i % 2 == 0) ? "1.png" : "2.png"
        uiImage.image = UIImage.init(named: name)
        let transition: CATransition = CATransition.init()
        transition.duration = 1.0
        transition.timingFunction = CAMediaTimingFunction.init(name: kCAMediaTimingFunctionEaseInEaseOut)
        transition.type = kCATransitionFade
        uiImage.layer.add(transition, forKey: nil)
        i += 1
    }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.