Anstatt zwei zu erstellen UIImageViews
, erscheint es logisch, einfach die image
einer Ansicht zu ändern . Wenn ich das mache, gibt es dann eher eine Überblendung zwischen den beiden Bildern als einen sofortigen Wechsel?
Anstatt zwei zu erstellen UIImageViews
, erscheint es logisch, einfach die image
einer Ansicht zu ändern . Wenn ich das mache, gibt es dann eher eine Überblendung zwischen den beiden Bildern als einen sofortigen Wechsel?
Antworten:
Bearbeiten: Es gibt eine bessere Lösung von @algal unten .
Eine andere Möglichkeit, dies zu tun, ist die Verwendung vordefinierter CAAnimation-Übergänge:
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;
Weitere Informationen finden Sie im Beispielprojekt "View Transitions" von Apple: https://developer.apple.com/library/content/samplecode/ViewTransitions/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007411
Mit den neuen blockbasierten UIKit animation
Methoden kann es viel einfacher sein .
Angenommen, der folgende Code befindet sich im Ansichts-Controller, und die UIImageView, die Sie auflösen möchten, ist eine Unteransicht von self.view, die über die Eigenschaft adressierbar ist. self.imageView
Dann benötigen Sie lediglich :
UIImage * toImage = [UIImage imageNamed:@"myname.png"];
[UIView transitionWithView:self.imageView
duration:5.0f
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
self.imageView.image = toImage;
} completion:nil]
Getan.
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, 4 & 5
let toImage = UIImage(named:"myname.png")
UIView.transition(with: self.imageView,
duration: 0.3,
options: .transitionCrossDissolve,
animations: {
self.imageView.image = toImage
},
completion: nil)
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
Ja, was Sie sagen, ist absolut richtig und das ist der Weg, es zu tun. Ich habe diese Methode geschrieben und verwende sie immer, um mein Bild auszublenden. Ich beschäftige mich CALayer
damit. Dazu müssen Sie 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 tun, um ein Bild auszublenden. Nachdem es ausgeblendet ist. Sie entfernen es einfach aus der Übersicht (was ist UIImageView
). [imageView removeFromSuperview]
.
Sie können die Einblendfunktion auch in eine Unterklasse packen, um sie dann wie im folgenden Beispiel als allgemeine UIImageView zu verwenden:
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 Weisen Sie tatsächlich die Fade-in implementieren in der setImage:
Funktion kann, ändern und eine der anderen hervorragenden Beispiele in den anderen Antworten auf diese Frage beschrieben werden könnten - eine zusätzliche on-the-fly zu schaffen , UIImageView
wie ich bin hier Macht zu tun 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 Proof of Concept gedacht und bleibt im Interesse der Klarheit und Fokussierung relevant, indem wichtiger nicht verwandter Code weggelassen wird. Bitte kopieren Sie es nicht einfach blind.
Ich brauchte den Übergang, um ihn auf unbestimmte Zeit zu wiederholen. Es dauerte eine Menge Versuch und Irrtum für diesen, aber ich bekam endlich das Endergebnis, das ich suchte. Dies sind Codefragmente zum Hinzufügen von Bildanimationen zu einer UIImageView in einer UITableViewCell.
Hier ist der relevante 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;
}
Nachdem ich UIView.transition()
mit der .transitionCrossDissolve
Option herumgespielt und Probleme mit der Option festgestellt hatte (ich habe versucht, Bilder zu animieren, die sich in einer UIImageView ändern, und der Übergang erfolgte sofort ohne Animation), stellte ich fest, dass Sie nur eine weitere Option hinzufügen müssen, mit der Sie Eigenschaften animieren können, die sich in der Ansicht ändern ( Swift 4.2 ):
UIView.transition(with: self.imageView,
duration: 1,
options: [.allowAnimatedContent, .transitionCrossDissolve],
animations: { self.imageView.image = newImage },
completion: nil)
Außerdem: Wenn Ihre Bildansicht Unteransichten enthält, wird diese ebenfalls neu gezeichnet und kann Animationen verhindern. Zum Beispiel hatte ich eine Unteransicht mit Unschärfe in meiner Bildansicht und in diesem Fall funktioniert die Animation nicht. Also habe ich einfach meine Ansichtshierarchie geändert und die Unschärfe in eine eigene Ansicht verschoben und über imageView platziert.
Durch die Verwendung der highlightedImage
Eigenschaft kann dies etwas einfacher gemacht werden. Hier ist ein Beispiel in Swift 3. Stellen Sie zuerst sowohl das normale als auch das hervorgehobene Bild ein:
let imageView = UIImageView(image: UIImage(named: "image"), highlightedImage: UIImage(named: "highlightedImage"))
Und wenn Sie zwischen diesen animierten wechseln möchten:
UIView.transition(with: imageView, duration: 0.3, options: .transitionCrossDissolve, animations: { self.imageView.isHighlighted = !self.imageView.isHighlighted}, completion: .none)