Wie animiere ich die Bildänderung in einer UIImageView?


198

Ich habe ein UIImageViewmit einem Bild. Jetzt habe ich ein komplett neues Bild (Grafikdatei) und möchte das hier anzeigen UIImageView. Wenn ich nur setze

myImageView.image = newImage;

Das neue Bild ist sofort sichtbar. Nicht animierbar.

Ich möchte, dass es schön in das neue Bild übergeht. Ich dachte, vielleicht gibt es eine bessere Lösung, als nur eine neue UIImageViewzu erstellen und mit der Animation zu verschmelzen?


Antworten:


260

Ich bin nicht sicher, ob Sie UIViews mit Fade-Effekt animieren können, da anscheinend alle unterstützten Ansichtsübergänge in der UIViewAnimationTransitionAufzählung definiert sind . Der Fading-Effekt kann mit CoreAnimation erzielt werden. Beispiel für diesen Ansatz:

#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
Ihr Code funktionierte perfekt, wenn Sie von einem Bild zum anderen wechseln. Wissen Sie, wie es mit der automatischen Animation von Bildern in einer UIImageView (animationImages-Eigenschaft) funktioniert?
CedricSoubrie

Sie können versuchen, CAKeyFrameAnimation für die Inhaltseigenschaft der Ebene zu verwenden. Sie sind sich jedoch nicht sicher, ob der Effekt der gleiche ist. Oder legen Sie den Animationsdelegierten fest und starten Sie in der Rückruffunktion zum Delegieren die Animation zum nächsten Bild, wenn die vorherige Animation beendet ist.
Vladimir

2
Dies ist definitiv einfacher als das manuelle Überblenden einer separaten Bildansicht. Vielen Dank!
Kevlar

Nun, wenn sich der Frame der Bildansichten ändert, bleibt er in derselben Position. Das ist ein Deal Breaker!
Hfossli

@Fossli, meinst du, wenn sich der Frame während der Animation ändert? Das ist eine andere Frage als
Vladimir

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

ist eine andere Möglichkeit


1
einfach und eröffnet eine ganze Reihe weiterer Animationseffekte zwischen den Bildern.
Also

1
Hat das gleiche Problem, das @hfossli in Bezug auf Rahmenänderungen erwähnt hat. Die Animation wäre träge, wenn die Layouts währenddessen geändert würden.
Geva

1
Dies ist die beste Lösung, da sie mit anderen Animationen kombiniert werden kann.
Kelin

160

In den Worten von Michael Scott, halte es einfach dumm. Hier ist eine einfache Möglichkeit, dies in Swift 3 und Swift 4 zu tun :

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

3
Klappt wunderbar. Vielen Dank!
RobertoAllende

1
Uau toll!
Wusste

1
Dies ändert sich zu 1 Bild. Was ist, wenn ich eine Reihe von Bildern habe und diese einzeln mit Übergangsanimation anzeigen möchte?
Ammar Mujeeb

1
Mit dem Abschlussblock können Sie zum nächsten übergehen.
Zia

41

Hier ist ein Beispiel in Swift , bei dem zuerst ein neues Bild aufgelöst und dann eine Bouncy-Animation hinzugefügt wird:

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

Wenn imageViewdie Ansicht korrekt als Unteransicht hinzugefügt wurde, sollte beim Umschalten zwischen selected = falseto selected = truedas Bild mit einer Bouncy-Animation ausgetauscht werden . SNStockCellSelectionAccessoryViewImageGibt nur ein anderes Bild basierend auf dem aktuellen Auswahlstatus zurück, siehe unten:

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

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

Das folgende GIF-Beispiel ist etwas verlangsamt, die eigentliche Animation erfolgt schneller:

                                       UIImageView Bounce Animation Gif


16

Code:

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;

Beispiel:

UIImageView Beispiel aus Code

Spaß, ausführlichere Lösung : ( Umschalten auf einen Fingertipp )

    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

Versuche dies:

_imageView.image = image;
[_imageView.layer addAnimation:[CATransition animation] forKey:kCATransition];

swift: _imageView.layer.addAnimation (CATransition (), forKey: kCATransition)
Eugene Braginets

8

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

Verwendung:

myImageView.imageWithFade = myImage

6

Warum nicht versuchen?

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

Eine schnelle Version:

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

Dies setzt die UIImageView so, dass das Umschalten für immer wiederholt wird ... der Autor hat jedoch nur um eine Änderung gebeten :(
J-Dizzle

setAnimationRepeatCount
William Hu

SetAnimationRepeatCount ändert nichts. Es hört nie auf
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

Hier gibt es verschiedene Ansätze: UIAnimations meiner Erinnerung nach klingt es nach Ihrer Herausforderung.

Edit: zu faul von mir :)

In dem Beitrag bezog ich mich auf diese Methode:

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

Aber anstatt den Rahmen zu animieren, animieren Sie das 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

Ab iOS 5 ist dies weitaus einfacher:

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

4
Das hilft nicht beim ursprünglichen Problem, nämlich dass Sie bereits ein Bild angezeigt haben und zu einem neuen Bild
überblenden

4
richtig .. diese Antwort löst die Frage nicht. Die Frage war nicht, wie man die Bildansicht einblendet, sondern von einem alten Bild zu einem neuen Bild. Animationsblöcke wurden in iOS 4 eingeführt.
Bastian

2

Swift 4 Das ist einfach großartig

  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

Vladimir's Antwort ist perfekt, aber jeder wie ich, der nach einer schnellen Lösung sucht

Diese Lösung ist für die schnelle Version 4.2 geeignet

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
    }

Sie können diese Methode von überall aus aufrufen. Das Bild wird mit Animation zum nächsten (Bild) geändert.

Verwenden Sie für Swift Version 4.0 die folgende Lösung

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
    }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.