如何为 UIImageView 中的图像变化设置动画?
Posted
技术标签:
【中文标题】如何为 UIImageView 中的图像变化设置动画?【英文标题】:How to animate the change of image in an UIImageView? 【发布时间】:2011-02-19 13:05:30 【问题描述】:我有一个带有图像的UIImageView
。现在我有一个全新的图像(图形文件),并想在这个UIImageView
中显示它。如果我只是设置
myImageView.image = newImage;
新图像立即可见。不可动画。
我希望它很好地淡入新图像。我想也许有比仅仅创建一个新的UIImageView
并与动画混合更好的解决方案?
【问题讨论】:
***.com/questions/7638831/… 【参考方案1】:斯威夫特 5:
处理collectionView时。仅重新加载一项或几项带有动画的项目。我在更改单元格图像时尝试了一些不同的动画选项,没有区别,所以我这里不指明动画名称。
UIView.animate(withDuration: 1.0) [weak self] in
guard let self = self else return print("gotchya!")
self.collectionView.reloadItems(at: [indexPath])
【讨论】:
【参考方案2】:Swift 5 扩展:
extension UIImageView
func setImage(_ image: UIImage?, animated: Bool = true)
let duration = animated ? 0.3 : 0.0
UIView.transition(with: self, duration: duration, options: .transitionCrossDissolve, animations:
self.image = image
, completion: nil)
【讨论】:
这应该是这个问题的公认答案。【参考方案3】: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)
【讨论】:
【参考方案4】:弗拉基米尔的回答很完美,但是像我这样正在寻找快速解决方案的人
此解决方案适用于 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
【讨论】:
【参考方案5】:用迈克尔斯科特的话来说,保持简单愚蠢。 这是在 Swift 3 和 Swift 4 中执行此操作的简单方法:
UIView.transition(with: imageView,
duration: 0.75,
options: .transitionCrossDissolve,
animations: self.imageView.image = toImage ,
completion: nil)
【讨论】:
像魅力一样工作。谢谢! Uau 太棒了!这么久都不知道这个该死的:) 这将变为 1 张图片。如果我有一组图像并想用过渡动画逐个显示怎么办? 您可以使用完成块过渡到下一个。 最好的解决方案在这里!【参考方案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 设置为永远重复切换...但是作者只是要求更改:(setAnimationRepeatCount
SetAnimationRepeatCount 不会改变任何东西。它永远不会停止【参考方案7】:
使用 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
【讨论】:
【参考方案8】:[UIView transitionWithView:textFieldimageView
duration:0.2f
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^
imageView.image = newImage;
completion:nil];
是另一种可能
【讨论】:
简单并在图像之间开辟了一系列其他动画效果。 与@hfossli 提到的关于帧更改的问题相同。如果在此期间更改布局,动画将变得迟缓。 这是最好的解决方案,因为它可以与其他动画结合使用。【参考方案9】:代码:
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;
示例:
有趣、更详细的解决方案:(点击切换)
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");
【讨论】:
【参考方案10】:这是 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
作为子视图正确添加到视图中,则在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 例子有点慢,实际的动画发生得更快:
【讨论】:
【参考方案11】:试试这个:
_imageView.image = image;
[_imageView.layer addAnimation:[CATransition animation] forKey:kCATransition];
【讨论】:
swift: _imageView.layer.addAnimation(CATransition(), forKey: kCATransition)【参考方案12】: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;
【讨论】:
【参考方案13】:从 ios 5 开始,这个就简单多了:
[newView setAlpha:0.0];
[UIView animateWithDuration:0.4 animations:^
[newView setAlpha:0.5];
];
【讨论】:
这对原始问题没有帮助,即您已经显示了一张图像,并且想要交叉淡入淡出到新图像...... 对..这个答案不能解决问题。问题不是如何在图像视图中淡入淡出,而是从旧图像淡入到新图像。 iOS 4 中引入了动画块。【参考方案14】:这里有几种不同的方法: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];
【讨论】:
【参考方案15】:我不确定您是否可以为 UIView 设置渐变效果,因为似乎所有支持的视图转换都在 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];
【讨论】:
您的代码在从一张图像转到另一张图像时运行良好。你知道如何让它与 UIImageView 中的图像自动动画一起工作吗(animationImages 属性)? 您可以尝试使用 CAKeyFrameAnimation 作为图层的内容属性,但不确定效果是否相同。或者设置动画委托,当上一个动画完成时,在委托回调函数中开始动画到下一个图像。 这绝对比手动交叉淡化单独的图像视图更简单。谢谢! 好吧.. 如果 imageviews 框架发生变化,那么它会保持在原来的位置.. 那是一个交易破坏者! @Fossli,您的意思是在动画期间帧发生变化时?那是一个不同的问题以上是关于如何为 UIImageView 中的图像变化设置动画?的主要内容,如果未能解决你的问题,请参考以下文章