wake-up-neo.com

Ausblenden/auflösen, wenn das Bild von UIImageView geändert wird

Anstatt zwei UIImageViews zu erstellen, erscheint es logisch, einfach die image einer Ansicht zu ändern. Wenn ich das tue, gibt es dann sowieso eine Überblendung zwischen den beiden Bildern und nicht eine Sofort-Umschaltung?

152
Josh Kahane

Edit: Es gibt eine bessere Lösung von @algal unterhalb von .

Eine andere Möglichkeit besteht darin, vordefinierte CAAnimation-Übergänge zu verwenden:

CATransition *transition = [CATransition animation];
transition.duration = 0.25;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionFade;
transition.delegate = self;
[self.view.layer addAnimation:transition forKey:nil];
view1.hidden = YES;
view2.hidden = NO;

Siehe das View Transitions-Beispielprojekt von Apple: https://developer.Apple.com/library/content/samplecode/ViewTransitions/Introduction/Intro.html#//Apple_ref/doc/uid/DTS40007411

43
Mirkules

Mit den neuen blockbasierten UIKit-Animationsmethoden kann es wesentlich einfacher sein.

Angenommen, der folgende Code befindet sich im View-Controller, und die UIImageView, die Sie überblenden möchten, ist eine Unteransicht von self.view, die über die Eigenschaft self.imageView ansprechbar ist. Dann brauchen Sie nur noch:

UIImage * toImage = [UIImage imageNamed:@"myname.png"];
[UIView transitionWithView:self.imageView
                  duration:5.0f
                   options:UIViewAnimationOptionTransitionCrossDissolve
                animations:^{
                  self.imageView.image = toImage;
                } completion:nil];

Erledigt.

Und um es in Swift zu tun, ist es so:

let toImage = UIImage(named:"myname.png")
UIView.transitionWithView(self.imageView,
                          duration:5,
                          options: UIViewAnimationOptions.TransitionCrossDissolve,
                          animations: { self.imageView.image = toImage },
                          completion: nil)

Swift 3.0

 let toImage = UIImage(named:"myname.png")
 UIView.transition(with: self.imageView,
                   duration: 0.3,
                   options: .transitionCrossDissolve,
                   animations: {
                       self.imageView.image = toImage
                   },
                   completion: nil)
565
algal

Ja, was Sie sagen, ist absolut korrekt und das ist der Weg, es zu tun. Ich habe diese Methode geschrieben und verwende diese immer, um mein Bild einzublenden. Ich beschäftige mich mit CALayer. Sie müssen dazu Core Animation importieren. 

+ (void)fadeInLayer:(CALayer *)l
{
    CABasicAnimation *fadeInAnimate   = [CABasicAnimation animationWithKeyPath:@"opacity"];
    fadeInAnimate.duration            = 0.5;
    fadeInAnimate.repeatCount         = 1;
    fadeInAnimate.autoreverses        = NO;
    fadeInAnimate.fromValue           = [NSNumber numberWithFloat:0.0];
    fadeInAnimate.toValue             = [NSNumber numberWithFloat:1.0];
    fadeInAnimate.removedOnCompletion = YES;
    [l addAnimation:fadeInAnimate forKey:@"animateOpacity"];
    return;
}

Sie können das Gegenteil für das Ausblenden eines Bildes tun. Nachdem es ausgeblendet ist. Sie entfernen es einfach aus dem Überblick (was UIImageView ist). [imageView removeFromSuperview].

6

Für Swift 3.0.1:

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

Referenz: https://Gist.github.com/licvido/bc22343cacfa3a8ccf88

6

Sie können die Einblendfunktion auch in eine Unterklasse packen, um sie dann wie eine übliche UIImageView zu verwenden, wie im folgenden Beispiel:

IMMFadeImageView *fiv=[[IMMFadeImageView alloc] initWithFrame:CGRectMake(10, 10, 50, 50)];
[self.view addSubview:fiv];
fiv.image=[UIImage imageNamed:@"initialImage.png"];
fiv.image=[UIImage imageNamed:@"fadeinImage.png"];  // fades in

Eine mögliche Implementierung folgt. 

Hinweis: Die Art und Weise, wie Sie das Fade-In in der setImage:-Funktion tatsächlich implementieren, kann sich ändern und könnte eines der anderen hervorragenden Beispiele sein, die in den anderen Antworten auf diese Frage beschrieben werden. Dadurch wird eine zusätzliche On-the-fly-UIImageView als I ' Hier zu tun, kann in Ihrer spezifischen Situation ein inakzeptabler Aufwand sein.

IMMFadeImageView.h :

#import <UIKit/UIKit.h>

@interface IMMFadeImageView : UIImageView
@property (nonatomic,assign) float fadeDuration;
@end

IMMFadeImageView.m :

#import "IMMFadeImageView.h"

@implementation IMMFadeImageView
@synthesize fadeDuration;

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.fadeDuration=1;
    }
    return self;
}
-(void)setImage:(UIImage *)newImage{

    if(!self.image||self.fadeDuration<=0){
        super.image=newImage;
    } else {
        UIImageView *iv=[[UIImageView alloc] initWithFrame:self.bounds];
        iv.contentMode=self.contentMode;
        iv.image=super.image;
        iv.alpha=1;
        [self addSubview:iv];
        super.image=newImage;
        [UIView animateWithDuration:self.fadeDuration delay:0 options:UIViewAnimationCurveEaseInOut animations:^{
            iv.alpha=0;
        } completion:^(BOOL finished) {
            [iv removeFromSuperview];
        }];
    }
}

Der obige Code basiert auf einigen Annahmen (einschließlich der Aktivierung von ARC in Ihrem XCode-Projekt), ist nur als Konzeptnachweis gedacht und bleibt im Interesse der Klarheit und des Fokus relevant, indem er wichtigen, nicht zusammenhängenden Code weglässt. Bitte kopiere es nicht einfach blind.

5
magma

Ich musste den Übergang unendlich oft wiederholen. Es dauerte eine Menge Versuch und Irrtum, aber ich hatte endlich das Endergebnis, nach dem ich gesucht hatte. Dies sind Codeausschnitte zum Hinzufügen von Bildanimationen zu einer UIImageView in einer UITableViewCell.

Hier ist der entsprechende Code:

@interface SomeViewController ()
@property(nonatomic, strong) NSMutableArray *imagesArray;
@property(nonatomic, assign) NSInteger varietyImageAnimationIndex;
@property(nonatomic, assign) BOOL varietyImagesAnimated;
@end

@implementation SomeViewController
@synthesize imagesArray;
@synthesize varietyImageAnimationIndex;
@synthesize varietyImagesAnimated;
...

// NOTE: Initialize the array of images in perhaps viewDidLoad method.

-(void)animateImages
{
    varietyImageAnimationIndex++;

    [UIView transitionWithView:varietyImageView
                      duration:2.0f
                       options:UIViewAnimationOptionTransitionCrossDissolve
                    animations:^{
                        varietyImageView.image = [imagesArray objectAtIndex:varietyImageAnimationIndex % [imagesArray count]];
                    } completion:^(BOOL finished) {
                        [self animateImages];
                    }];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   ...
        [cell.imageView setImage:[imagesArray objectAtIndex:0]];


        [self setVarietyImageView:cell.imageView];

        if (! varietyImagesAnimated)
        {
            varietyImagesAnimated = YES;
            [self animateImages];
        }

    ...
    return cell;
}
3
Christopher

Nachdem ich mit UIView.transition() herumgespielt hatte und Probleme mit der .transitionCrossDissolve-Option hatte (ich versuchte, Bilder zu animieren, die sich in einem UIImageView ändern und der Übergang sofort ohne Animation erfolgte), stellte ich fest, dass Sie nur noch eine weitere Option hinzufügen müssen, mit der Sie die Eigenschaften von innerhalb von Ansicht ( Swift 4.2 ):

UIView.transition(with: self.imageView,
                   duration: 1,
                   options: [.allowAnimatedContent, .transitionCrossDissolve],
                   animations: { self.imageView.image = newImage },
                   completion: nil)

Außerdem: Wenn Sie in Ihrer imageView Unteransichten haben, wird diese ebenfalls neu gezeichnet und kann Animationen verhindern. Ich hatte zum Beispiel eine Unteransicht mit Unschärfe in meiner imageView und in diesem Fall funktioniert die Animation nicht. Also habe ich einfach meine Ansichtshierarchie geändert und verwischen Sie die Unschärfe auf ihre eigene Ansicht und stellen Sie sie über imageView.

0
Pavel

Mit der highlightedImage-Eigenschaft kann dies etwas einfacher gemacht werden. Hier ein Beispiel in Swift 3. Legen Sie zunächst das normale und das hervorgehobene Bild fest:

let imageView = UIImageView(image: UIImage(named: "image"), highlightedImage: UIImage(named: "highlightedImage"))

Und wenn Sie zwischen den animierten wechseln möchten:

UIView.transition(with: imageView, duration: 0.3, options: .transitionCrossDissolve, animations: { self.imageView.isHighlighted = !self.imageView.isHighlighted}, completion: .none)
0
Jens Schwarzer

Dies ist meiner Meinung nach der kürzeste Weg. Erstellen Sie eine UIView-Animation, und legen Sie sie in Ihrem imageView fest.

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[myImageView setAlpha:0.0];
[UIView commitAnimations];
0
divyenduz