Invece di crearne due UIImageViews
, sembra logico semplicemente cambiare la image
vista di una. Se lo faccio, c'è comunque una dissolvenza dissolvenza / croce tra le due immagini piuttosto che un passaggio istantaneo?
Invece di crearne due UIImageViews
, sembra logico semplicemente cambiare la image
vista di una. Se lo faccio, c'è comunque una dissolvenza dissolvenza / croce tra le due immagini piuttosto che un passaggio istantaneo?
Risposte:
Modifica: di seguito è disponibile una soluzione migliore da @algal .
Un altro modo per farlo è utilizzare le transizioni CAAnimation predefinite:
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;
Vedi il progetto di esempio View Transitions di Apple: https://developer.apple.com/library/content/samplecode/ViewTransitions/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007411
Può essere molto più semplice usando i nuovi UIKit animation
metodi basati su blocchi .
Supponiamo che il seguente codice sia nel controller di visualizzazione e che UIImageView che si desidera dissolvere in modo incrociato sia una sottoview di self.view indirizzabile tramite la proprietà self.imageView
Quindi tutto ciò che serve è:
UIImage * toImage = [UIImage imageNamed:@"myname.png"];
[UIView transitionWithView:self.imageView
duration:5.0f
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
self.imageView.image = toImage;
} completion:nil]
Fatto.
E farlo in Swift, è così:
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 e 5
let toImage = UIImage(named:"myname.png")
UIView.transition(with: self.imageView,
duration: 0.3,
options: .transitionCrossDissolve,
animations: {
self.imageView.image = toImage
},
completion: nil)
Per Swift 3.0.1:
UIView.transition(with: self.imageView,
duration:0.5,
options: .transitionCrossDissolve,
animations: { self.imageView.image = newImage },
completion: nil)
Riferimento: https://gist.github.com/licvido/bc22343cacfa3a8ccf88
Sì, quello che dici è assolutamente corretto e questo è il modo di farlo. Ho scritto questo metodo e lo uso sempre per Dissolvenza nella mia immagine. Mi occupo CALayer
di questo. Per questo è necessario importare Core Animation.
+ (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;
}
Potresti fare il contrario per Dissolvenza di un'immagine. Dopo che svanisce. Lo rimuovi da Superview (che è UIImageView
). [imageView removeFromSuperview]
.
È inoltre possibile impacchettare la funzionalità di dissolvenza in una sottoclasse, in modo da poterla utilizzare come UIImageView comune, come nell'esempio seguente:
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
Segue una possibile implementazione.
Nota: il modo in cui implementate la dissolvenza nella setImage:
funzione può cambiare e potrebbe essere uno degli altri eccellenti esempi descritti nelle altre risposte a questa domanda: la creazione di un ulteriore al volo UIImageView
come sto facendo qui potrebbe essere un sovraccarico inaccettabile nella tua situazione specifica .
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];
}];
}
}
Il codice sopra riportato si basa su alcuni presupposti (incluso l'ARC abilitato nel progetto XCode), è inteso solo come una prova del concetto e, nell'interesse della chiarezza e dell'attenzione, rimane rilevante omettendo un codice non correlato importante. Per favore non copiarlo e incollarlo alla cieca.
Avevo bisogno che la transizione si ripetesse indefinitamente. Ci sono volute molte prove ed errori per questo, ma alla fine ho ottenuto il risultato finale che stavo cercando. Questi sono frammenti di codice per l'aggiunta di animazioni di immagini a UIImageView in UITableViewCell.
Ecco il codice pertinente:
@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;
}
Dopo aver giocato UIView.transition()
e avuto problemi con l' .transitionCrossDissolve
opzione (stavo cercando di animare le immagini cambiando all'interno di una UIImageView e la transizione si è verificata istantaneamente senza animazione) ho scoperto che devi solo aggiungere un'altra opzione che ti consente di animare le proprietà cambiando all'interno della vista ( Swift 4.2 ):
UIView.transition(with: self.imageView,
duration: 1,
options: [.allowAnimatedContent, .transitionCrossDissolve],
animations: { self.imageView.image = newImage },
completion: nil)
Inoltre: se hai delle visualizzazioni secondarie su imageView, anche questa verrà ridisegnata e potrebbe impedire l'animazione. Ad esempio, ho avuto una subview con sfocatura sul mio imageView e in tal caso l'animazione non funziona. Quindi ho appena cambiato la mia gerarchia di visualizzazione e ho spostato la sfocatura nella sua vista e l'ho messa su imageView.
Usando la highlightedImage
proprietà questo può essere reso un po 'più semplice. Ecco un esempio in Swift 3. Innanzitutto imposta sia l'immagine normale che quella evidenziata:
let imageView = UIImageView(image: UIImage(named: "image"), highlightedImage: UIImage(named: "highlightedImage"))
E quando vuoi cambiare tra quelli animati:
UIView.transition(with: imageView, duration: 0.3, options: .transitionCrossDissolve, animations: { self.imageView.isHighlighted = !self.imageView.isHighlighted}, completion: .none)