UIImageViewで画像の変化をアニメーション化する方法は?


199

私が持っているUIImageViewイメージで。これで完全に新しい画像(グラフィックファイル)ができたので、これに表示したいと思いますUIImageView。設定したら

myImageView.image = newImage;

新しい画像がすぐに表示されます。アニメートできません。

新しい画像にうまくフェードインしたい。UIImageViewその上に新しいものを作成してアニメーションとブレンドするよりも良い解決策があるのではないかと思いました。


回答:


260

サポートされているすべてのビュー遷移がUIViewAnimationTransition列挙で定義されているように見えるため、フェード効果を使用してUIViewをアニメーション化できるかどうかはわかりません。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を使用してみてください。または、アニメーションデリゲートを設定し、デリゲートコールバック関数で、前のアニメーションが終了すると次の画像へのアニメーションを開始します。
ウラジミール

2
これは、個別の画像ビューを手動でクロスフェードするよりも明らかに簡単です。ありがとう!
ケブラー

まあ.. imageviewsフレームが変更された場合、それは同じ位置に留まります。それは取引ブレーカーです!
hfossli 2012

@Fossli、あなたはアニメーション中にフレームが変わるときを意味しますか?それはそれから別の質問です
ウラジミール

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

別の可能性です


1
シンプルで、画像間の他のアニメーション効果の全範囲を開きます。
つまり、

1
フレームの変更に関して@hfossliが言及したのと同じ問題があります。その間にレイアウトを変更すると、アニメーションが遅くなります。
Geva、2014

1
これは他のアニメーションと組み合わせることができるため、最適なソリューションです。
kelin

161

マイケル・スコットの言葉では、それは単純な愚かさを保ちます。これを行う簡単な方法を次に示しますSwift 3Swift 4で

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

3
魅力のように機能します。ありがとう!
RobertoAllende

1
すごい!これについては長い間知らなかった:)
サビランド

1
これは1つの画像に変わります。画像の配列があり、トランジションアニメーションで1つずつ表示したい場合はどうなりますか?
Ammar Mujeeb

1
完了ブロックを使用して、次のブロックに移行できます。
Zia

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がサブビューとしてビューに正しく追加されている場合、selected = falseto 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

setAnimationRepeatCount
William Hu

SetAnimationRepeatCountは何も変更しません。終わらない
Yucel Bayram

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];

ただし、フレームをアニメーション化する代わりに、アルファをアニメーション化します。

[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
それはあなたがイメージがすでに表示されていて、新しいイメージにフェードを横断したいということです元の問題を解決しない...
ケンドールHelmstetter Gelner

4
正しい..この答えは質問を解決しません。問題は、イメージビューをフェードインする方法ではなく、古いイメージから新しいイメージにフェードインすることでした。アニメーションブロックはiOS 4で導入されました
Bastian

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
    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.