Daripada membuat dua UIImageViews
, tampaknya logis untuk hanya mengubah image
pandangan satu. Jika saya melakukan itu, apakah ada pula yang memiliki fade / cross melarutkan antara dua gambar daripada saklar instan?
Daripada membuat dua UIImageViews
, tampaknya logis untuk hanya mengubah image
pandangan satu. Jika saya melakukan itu, apakah ada pula yang memiliki fade / cross melarutkan antara dua gambar daripada saklar instan?
Jawaban:
Sunting: ada solusi yang lebih baik dari @algal di bawah ini .
Cara lain untuk melakukan ini adalah dengan menggunakan transisi CAAnimation yang telah ditentukan:
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;
Lihat proyek contoh Lihat Transisi dari Apple: https://developer.apple.com/library/content/samplecode/ViewTransitions/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007411
Ini bisa jauh lebih sederhana menggunakan berbasis blok baru, UIKit animation
metode .
Misalkan kode berikut ada di view controller, dan UIImageView yang ingin Anda belah silang adalah subview dari self.view dialamatkan melalui properti self.imageView
Maka semua yang Anda butuhkan adalah:
UIImage * toImage = [UIImage imageNamed:@"myname.png"];
[UIView transitionWithView:self.imageView
duration:5.0f
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
self.imageView.image = toImage;
} completion:nil]
Selesai
Dan untuk melakukannya di Swift, seperti ini:
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)
Untuk Swift 3.0.1:
UIView.transition(with: self.imageView,
duration:0.5,
options: .transitionCrossDissolve,
animations: { self.imageView.image = newImage },
completion: nil)
Referensi: https://gist.github.com/licvido/bc22343cacfa3a8ccf88
Ya apa yang Anda katakan benar-benar benar dan itulah cara untuk melakukannya. Saya menulis metode ini & selalu menggunakan ini untuk Fade dalam gambar saya. Saya berurusan dengan CALayer
ini. Anda perlu mengimpor Core Animation untuk ini.
+ (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;
}
Anda bisa melakukan yang sebaliknya untuk memudar gambar. Setelah itu memudar. Anda cukup menghapusnya dari superview (yang UIImageView
). [imageView removeFromSuperview]
.
Anda juga bisa mengemas fitur fade-in dalam subclass, sehingga Anda bisa menggunakannya sebagai UIImageView yang umum, seperti dalam contoh berikut:
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
Kemungkinan implementasi mengikuti.
Catatan: cara Anda benar-benar mengimplementasikan fade-in pada setImage:
fungsi dapat berubah, dan bisa menjadi salah satu contoh bagus lainnya yang dijelaskan dalam jawaban lain untuk pertanyaan ini - membuat on-the-fly tambahan UIImageView
seperti yang saya lakukan di sini mungkin menjadi overhead yang tidak dapat diterima dalam situasi spesifik Anda .
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];
}];
}
}
Kode di atas bergantung pada beberapa asumsi (termasuk ARC yang diaktifkan dalam proyek XCode Anda), hanya dimaksudkan sebagai bukti konsep, dan demi kejelasan dan fokus, kode tersebut tetap relevan dengan menghilangkan kode penting yang tidak terkait. Tolong jangan hanya copy-paste secara membabi buta.
Saya membutuhkan transisi untuk mengulang tanpa batas. Butuh BANYAK percobaan dan kesalahan untuk yang satu ini tetapi saya akhirnya mendapatkan hasil akhir yang saya cari. Ini adalah cuplikan kode untuk menambahkan animasi gambar ke UIImageView di UITableViewCell.
Ini kode yang relevan:
@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;
}
Setelah bermain-main dengan UIView.transition()
dan mendapatkan masalah dengan .transitionCrossDissolve
opsi (saya mencoba untuk menganimasikan gambar berubah dalam satu UIImageView dan transisi terjadi secara instan tanpa animasi) Saya menemukan bahwa Anda hanya perlu menambahkan satu opsi lagi yang memungkinkan Anda menghidupkan properti yang berubah di dalam tampilan ( Swift 4.2 ):
UIView.transition(with: self.imageView,
duration: 1,
options: [.allowAnimatedContent, .transitionCrossDissolve],
animations: { self.imageView.image = newImage },
completion: nil)
Selain itu: jika Anda memiliki subview pada imageView Anda, itu akan digambar ulang juga dan itu dapat mencegah animasi. Sebagai contoh, saya memiliki subview dengan blur pada imageView saya dan dalam hal ini animasi tidak berfungsi. Jadi saya baru saja mengubah hierarki tampilan saya dan memindahkan blur ke tampilan sendiri dan meletakkannya di atas imageView.
Dengan menggunakan highlightedImage
properti ini dapat dibuat sedikit lebih sederhana. Berikut ini contoh dalam Swift 3. Pertama-tama atur baik gambar normal maupun yang disorot:
let imageView = UIImageView(image: UIImage(named: "image"), highlightedImage: UIImage(named: "highlightedImage"))
Dan ketika Anda ingin mengubah antara animasi tersebut:
UIView.transition(with: imageView, duration: 0.3, options: .transitionCrossDissolve, animations: { self.imageView.isHighlighted = !self.imageView.isHighlighted}, completion: .none)