Замість того, щоб створити два UIImageViews
, здається логічним просто змінити image
один погляд. Якщо я це роблю, чи все-таки виникає розмикання / перехрестя між двома зображеннями, а не миттєвим перемикачем?
Замість того, щоб створити два UIImageViews
, здається логічним просто змінити image
один погляд. Якщо я це роблю, чи все-таки виникає розмикання / перехрестя між двома зображеннями, а не миттєвим перемикачем?
Відповіді:
Редагувати: є краще рішення від @algal нижче .
Ще один спосіб зробити це за допомогою попередньо визначених переходів CAAnimation:
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;
Дивіться приклад проекту Переходи переходів від Apple: https://developer.apple.com/library/content/samplecode/ViewTransitions/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007411
Це може бути набагато простіше, використовуючи нові UIKit animation
методи на основі блоків .
Припустимо, наступний код знаходиться в контролері перегляду, а UIImageView, який ви хочете перехрестити, - це підвид самовигляду self.view, адресованого через властивість. self.imageView
Тоді все, що вам потрібно:
UIImage * toImage = [UIImage imageNamed:@"myname.png"];
[UIView transitionWithView:self.imageView
duration:5.0f
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
self.imageView.image = toImage;
} completion:nil]
Зроблено.
А робити це у Свіфті - це так:
let toImage = UIImage(named:"myname.png")
UIView.transitionWithView(self.imageView,
duration:5,
options: UIViewAnimationOptions.TransitionCrossDissolve,
animations: { self.imageView.image = toImage },
completion: nil)
Швидкий 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)
Для Swift 3.0.1:
UIView.transition(with: self.imageView,
duration:0.5,
options: .transitionCrossDissolve,
animations: { self.imageView.image = newImage },
completion: nil)
Довідка: https://gist.github.com/licvido/bc22343cacfa3a8ccf88
Так, те, що ви говорите, абсолютно правильне, і це спосіб зробити це. Я написав цей метод і завжди використовую це для Fade в своєму образі. Я CALayer
для цього маю справу . Для цього вам потрібно імпортувати 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;
}
Ви можете зробити навпаки, щоб зменшити зображення. Після того як він згасає. Ви просто видаляєте його з нагляду (який є UIImageView
). [imageView removeFromSuperview]
.
Ви також можете упакувати функцію зникнення в підклас, щоб потім ви могли використовувати її як загальний UIImageView, як у наступному прикладі:
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
Наступна можлива реалізація.
Примітка: те, як ви реально реалізуєте setImage:
функцію зменшення функцій, може змінитися, і це може бути одним із інших чудових прикладів, описаних в інших відповідях на це питання - створення додаткового на ходу UIImageView
, що я роблю тут, можливо бути неприйнятним накладними витратами у вашій конкретній ситуації .
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];
}];
}
}
Вищенаведений код покладається на кілька припущень (включаючи включення ARC у вашому проекті XCode), призначений лише як доказ концепції, а в інтересах ясності та уваги він залишається актуальним, опускаючи важливий непов'язаний код. Будь ласка, не просто скопіюйте його та наосліп.
Мені потрібен був перехід, щоб повторити нескінченно. Для цього було потрібно багато спроб та помилок, але я нарешті отримав кінцевий результат, який я шукав. Це фрагменти коду для додавання анімації зображень до UIImageView в UITableViewCell.
Ось відповідний код:
@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;
}
Погравши з UIView.transition()
та отримавши проблеми з .transitionCrossDissolve
опцією (я намагався анімувати зображення, що змінюються в одному UIImageView, і перехід відбувся миттєво без анімації), я з’ясував, що вам просто потрібно додати ще одну опцію, яка дозволяє вам анімувати властивості, що змінюються всередині подання ( Швидкий 4.2 ):
UIView.transition(with: self.imageView,
duration: 1,
options: [.allowAnimatedContent, .transitionCrossDissolve],
animations: { self.imageView.image = newImage },
completion: nil)
Крім того: якщо у вас є якісь підгляди на imageView, він також буде перероблений, і це може перешкодити анімації. Наприклад, у мене було перегляд із розмиттям на моєму imageView, і в цьому випадку анімація не працює. Тож я просто змінив ієрархію перегляду і переміщую розмиття до власного перегляду та перекладаю його на imageView.
Використовуючи highlightedImage
властивість, це можна зробити трохи простіше. Ось приклад у Swift 3. Спочатку встановіть як звичайне, так і виділене зображення:
let imageView = UIImageView(image: UIImage(named: "image"), highlightedImage: UIImage(named: "highlightedImage"))
І коли ви хочете перейти між цими анімованими:
UIView.transition(with: imageView, duration: 0.3, options: .transitionCrossDissolve, animations: { self.imageView.isHighlighted = !self.imageView.isHighlighted}, completion: .none)