【问题标题】:How to crossfade between 2 images on iPhone using Core Animation如何使用 Core Animation 在 iPhone 上的 2 个图像之间交叉淡入淡出
【发布时间】:2010-12-05 17:34:18
【问题描述】:

我这样做是为了学习如何在 iPhone 上使用 Core Animation 动画属性(而不是学习如何交叉淡化图像本身)。

阅读关于 SO 的类似问题让我相信它可以通过像这样为 UIImageView 的 layer 的 .contents 属性设置动画来完成:

UIImage *image1 = [UIImage imageNamed:@"someImage1.png"];
UIImage *image2 = [UIImage imageNamed:@"someImage2.png"];

self.imageView.image = image1;
[self.view addSubview:self.imageView];

CABasicAnimation *crossFade = [CABasicAnimation animationWithKeyPath:@"contents"];
crossFade.duration = 5.0;
self.imageView.layer.contents = image2;
[self.imageView.layer addAnimation:crossFade forKey:@"animateContents"];

我是否弄错了细节,或者这不可能。

更新:上面的代码产生了一个空白的 UIImageView。当我更改此行时:

self.imageView.layer.contents = image2.CGImage;

...我现在可以看到图像,但它不会淡入,它只是立即出现。

【问题讨论】:

    标签: iphone core-animation


    【解决方案1】:

    我的建议是只使用两个UIImageViews。上图是image1,下图是image2:

    - (void) crossfade {
        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationDuration:.5];
        imageView1.alpha = !imageView1.alpha;
        [UIView commitAnimations];
    }
    

    无论何时调用它,它都会在两个图像之间消失。如果您只想进行一次淡入淡出并在完成后删除第一张图像:

    - (void) crossfade {
        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationDuration:.5];
        [UIView setAnimationDelegate:imageView1];
        [UIView setAnimationDidStopSelector:@selector(removeFromSuperview)];
        imageView1.alpha = 0
        [UIView commitAnimations];
    }
    

    编辑:

    如果您正在寻找代码不起作用的原因,那是因为您只是将属性设置为新图像,然后添加了无用的动画。 CABasicAnimation 有 fromValue 和 toValue 需要设置,然后将该动画添加到图层,它应该做动画。不要手动设置内容。

    【讨论】:

    • 感谢您的回答,但我正在尝试了解 CA 动画属性和使用键路径的语法,而不是如何交叉淡入淡出图像本身。你知道我在代码示例中做错了什么吗?
    【解决方案2】:

    你快到了。

    CABasicAnimation *crossFade = [CABasicAnimation animationWithKeyPath:@"contents"];
    crossFade.duration = 5.0;
    crossFade.fromValue = image1.CGImage;
    crossFade.toValue = image2.CGImage;
    [self.imageView.layer addAnimation:crossFade forKey:@"animateContents"];
    

    请注意,动画独立于 UIImageView 的实际值/内容。因此,您需要

    self.imageView.image = image2;
    

    ...为您的图像设置最终结果。

    【讨论】:

    • 它工作,交叉淡入淡出图像。如何抑制编译器警告“从不兼容的指针类型传递 'setFromValue:' 的参数 1”
    • .fromValue 和 .toValue 期望一个指向 Objective-C 对象的指针,而不是像 CGImageRef 那样指向 CFType 的指针。因此你可以这样做:crossFade.fromValue = (id)(image1.CGImage); crossFade.toValue = (id)(image2.CGImage);
    • 可以对文本/背景颜色做类似的事情吗,例如在 UIButton 上?
    【解决方案3】:

    我在某个地方找到了这个 - 效果很好。

    斯威夫特

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

    对象

    UIImage * toImage = [UIImage imageNamed:@"image.png"];
    [UIView transitionWithView:self.view
                      duration:0.33f
                       options:UIViewAnimationOptionTransitionCrossDissolve
                    animations:^{
                        self.imageview.image = toImage;
                    } completion:NULL];
    

    【讨论】:

    • 在其他建议的解决方案失败的地方工作。
    • 直截了当、简单,没有覆盖等。谢谢。
    • 完美的解决方案,你拯救了我的一天
    • 这在 iOS 14.5 上对我来说完全没问题,并且是制作此动画的正确方法。
    【解决方案4】:
    extension UIImageView
    {
        func mySetImage(image:UIImage)
        {
            guard let currentImage = self.image where currentImage != image else { return }
            let animation = CATransition()
            animation.duration = 0.3
            animation.type = kCATransitionFade
            layer.add(animation, forKey: "ImageFade")
            self.image = image
        }
    }
    

    【讨论】:

    • 超级简单超级有效!谢谢。 IMO 最好的方法是扩展 UIImageView 并用这个糖覆盖 setImage
    • 同意。这是一个更简单的解决方案。
    • 两张图片的比较可能非常昂贵,我不建议将两张图片转换为PNG来比较它们是否相同。
    • 这是 IMO 的最佳答案
    • @steipete 当将此方法用于UITableViewCell imageView 时,这一点变得异常明显,它可能会被调用 10 次以上并导致大量延迟。
    【解决方案5】:
    - (void)viewDidLoad
    {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    self.navigationController.navigationBarHidden=false;
    UIImage *img=[UIImage imageNamed:@"images.jpeg"];
    imgview=[[UIImageView alloc]init];
    imgview.frame=CGRectMake(30,90, img.size.width, img.size.height);
    [self.view addSubview:imgview];
    [self animateImages];
    }
    - (void)animateImages
    {
    static int count = 0;
    NSArray *animationImages = @[[UIImage imageNamed:@"images.jpeg"], [UIImage imageNamed:@"images (1).jpeg"]];
    UIImage *image = [animationImages objectAtIndex:(count % [animationImages count])];
    
    [UIView transitionWithView:imgview
                      duration:2.0f // animation duration
                       options:UIViewAnimationOptionTransitionCrossDissolve
                    animations:^{
                        imgview.image = image;
                    } completion:^(BOOL finished) {
                        [self animateImages];
                        count++;
                    }];
    

    }

    【讨论】:

    • 交叉淡入淡出图像旋转器的好代码。很适合我。
    【解决方案6】:

    快速解决

    let image1:UIImage = UIImage(named: "someImage1")!;
    let image2:UIImage = UIImage(named: "someImage2")!;
    let crossFade:CABasicAnimation = CABasicAnimation(keyPath: "contents");
    crossFade.duration = 5.0;
    crossFade.fromValue = image1.CGImage;
    crossFade.toValue = image2.CGImage;
    imageView.layer.addAnimation(crossFade, forKey:"animateContents");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-29
      • 1970-01-01
      相关资源
      最近更新 更多