Bagaimana cara menganimasikan perubahan gambar di UIImageView?

199

Saya punya UIImageViewdengan gambar. Sekarang saya memiliki gambar yang sama sekali baru (file grafik), dan ingin menampilkannya di ini UIImageView. Jika saya hanya mengatur

myImageView.image = newImage;

gambar baru segera terlihat. Tidak dapat dianimasikan.

Saya ingin memudar dengan baik ke gambar baru. Saya pikir mungkin ada solusi yang lebih baik daripada hanya membuat yang baru UIImageViewdi atasnya dan menyatu dengan animasi?

profilProfile dontWatch
sumber

Jawaban:

260

Saya tidak yakin apakah Anda dapat menghidupkan UIViews dengan efek fade karena sepertinya semua transisi tampilan yang didukung didefinisikan dalam UIViewAnimationTransitionenumerasi. Efek fading dapat dicapai dengan menggunakan CoreAnimation. Contoh contoh untuk pendekatan ini:

#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];
Vladimir
sumber
2
Kode Anda berfungsi dengan baik saat berpindah dari satu gambar ke gambar lainnya. Apakah Anda tahu cara membuatnya bekerja dengan animasi gambar otomatis di UIImageView (properti animationImages)?
CedricSoubrie
Anda dapat mencoba menggunakan CAKeyFrameAnimation untuk properti konten layer, meskipun tidak yakin apakah efeknya akan sama. Atau atur delegasi animasi dan dalam fungsi panggil balik delegasi mulai menjiwai ke gambar berikutnya ketika animasi sebelumnya selesai.
Vladimir
2
Ini jelas lebih sederhana daripada crossfading secara manual tampilan gambar yang terpisah. Terima kasih!
Kevlar
Baiklah .. Jika bingkai tampilan gambar berubah maka ia tetap pada posisi yang sama .. itu adalah pemecah kesepakatan!
hfossli
@Fossli, maksud Anda ketika bingkai berubah selama animasi? Itu pertanyaan yang berbeda
Vladimir
368
[UIView transitionWithView:textFieldimageView
                  duration:0.2f
                   options:UIViewAnimationOptionTransitionCrossDissolve
                animations:^{
                    imageView.image = newImage;
                } completion:nil];

adalah kemungkinan lain

Ilker Baltaci
sumber
1
sederhana dan membuka seluruh jajaran efek animasi lainnya di antara gambar.
So Over It
1
Memiliki masalah yang sama yang @hfossli sebutkan mengenai perubahan bingkai. Animasi akan lamban jika tata letak diubah selama itu.
Geva
1
Ini adalah solusi terbaik, karena dapat dikombinasikan dengan animasi lain.
kelin
161

Dalam kata-kata Michael Scott, tetap bodoh sederhana. Berikut adalah cara sederhana untuk melakukan ini di Swift 3 dan Swift 4 :

UIView.transition(with: imageView,
                  duration: 0.75,
                  options: .transitionCrossDissolve,
                  animations: { self.imageView.image = toImage },
                  completion: nil)
Zia
sumber
3
Bekerja seperti pesona. Terima kasih!
RobertoAllende
1
Uau hebat! Tidak tahu tentang ini lama sekali :)
sabiland
1
Ini akan berubah menjadi 1 gambar. bagaimana jika saya memiliki serangkaian gambar dan ingin menunjukkan satu-per-satu dengan animasi transisi?
Ammar Mujeeb
1
Anda dapat menggunakan blok penyelesaian untuk transisi ke yang berikutnya.
Zia
41

Berikut adalah salah satu contoh di Swift yang pertama-tama akan memotong gambar baru dan kemudian menambahkan animasi goyang:

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

Jika imageViewbenar ditambahkan ke tampilan sebagai subview, Toggling antara selected = falseke selected = trueharus menukar gambar dengan animasi goyang. SNStockCellSelectionAccessoryViewImagecukup kembalikan gambar yang berbeda berdasarkan kondisi pemilihan saat ini, lihat di bawah:

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

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

Contoh GIF di bawah agak melambat, animasi sebenarnya terjadi lebih cepat:

                                       UIImageView memantul animasi Gif

Zorayr
sumber
16

Kode:

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;

Contoh:

UIImageView Contoh dari kode

Menyenangkan, Lebih Banyak Solusi Verbose : ( Beralih dengan satu ketukan )

    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");
J-Dizzle
sumber
10

Coba ini:

_imageView.image = image;
[_imageView.layer addAnimation:[CATransition animation] forKey:kCATransition];
Peter Stajger
sumber
swift: _imageView.layer.addAnimation (CATransition (), forKey: kCATransition)
Eugene Braginets
8

Dengan 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)
        }
    }
}

Pemakaian:

myImageView.imageWithFade = myImage
M. Nadeeshan
sumber
6

Kenapa tidak coba ini.

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

Versi cepat:

let animationsFrames = [UIImage(named: "image1.png"), UIImage(named: "image2.png")]
let animatedImageView = UIImageView()
animatedImageView.animationImages = animationsFrames
animatedImageView.animationRepeatCount = 1
animatedImageView.startAnimating()
William Hu
sumber
Ini mengatur UIImageView untuk mengulangi toggling selamanya ... penulis hanya meminta perubahan :(
J-Dizzle
setAnimationRepeatCount
William Hu
SetAnimationRepeatCount tidak mengubah apa pun. Tidak pernah berhenti
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;
kas-kad
sumber
3

Ada beberapa pendekatan berbeda di sini: UIAnimasi ke ingatan saya kedengarannya seperti tantangan Anda.

Sunting: terlalu malas padaku :)

Dalam posting, saya merujuk pada metode ini:

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

Tapi alih-alih animasi bingkai, Anda menghidupkan 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];
RickiG
sumber
2

Pada iOS 5 yang satu ini jauh lebih mudah:

[newView setAlpha:0.0];
[UIView animateWithDuration:0.4 animations:^{
    [newView setAlpha:0.5];
}];
Borut Tomazin
sumber
4
Itu tidak membantu masalah asli, yaitu bahwa Anda sudah memiliki gambar yang ditampilkan, dan ingin memudar silang ke gambar baru ...
Kendall Helmstetter Gelner
4
benar .. jawaban ini tidak menyelesaikan pertanyaan. Pertanyaannya bukan bagaimana memudar dalam tampilan gambar tetapi memudar dari gambar lama ke gambar baru. Blok animasi diperkenalkan di iOS 4.
Bastian
2

Swift 4 Ini luar biasa

  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)
Gurjinder Singh
sumber
1

Jawaban Vladimir sempurna, tetapi siapa pun seperti saya yang mencari solusi cepat

Solusi ini Berfungsi untuk versi cepat 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
    }

Anda dapat memanggil metode ini dari mana saja. Ini akan mengubah gambar ke yang berikutnya (gambar) dengan animasi.

Untuk Versi Swift 4.0 Gunakan solusi di bawah ini

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
    }
Saleh Enam Shohag
sumber