Вместо создания двух UIImageViews
, кажется логичным просто изменить image
одного вида. Если я это сделаю, есть ли когда-либо из-за того, что между этими двумя изображениями исчезает затухание/крест, а не мгновенный переключатель?
Затухание/растворение при изменении изображения UIImageView
Ответ 1
Изменить: есть лучшее решение @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;
См. проект примера View Transitions от Apple: https://developer.apple.com/library/content/samplecode/ViewTransitions/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007411
Ответ 2
Это может быть намного проще с использованием новых меток анимации UIKit на основе блоков.
Предположим, что в контроллере представления находится следующий код, а 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];
Готово.
И для этого в Swift это так:
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)
Ответ 3
Да, что вы говорите, абсолютно правильно, и это способ сделать это. Я написал этот метод и всегда использую его для 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;
}
Вы можете сделать обратное для Fade из изображения. После этого он исчезает. Вы просто удаляете его из супервизора (это UIImageView
). [imageView removeFromSuperview]
.
Ответ 4
Для 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
Ответ 5
Вы также можете упаковать функцию fade-in в подкласс, чтобы затем использовать его как обычный 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), предназначен только для доказательства концепции, и в интересах ясности и внимания он остается актуальным, опуская важный несвязанный код. Пожалуйста, не просто скопируйте его вслепую.
Ответ 6
Мне нужен переход, чтобы повторять бесконечно. Для этого потребовалось много проб и ошибок, но я, наконец, получил конечный результат, который я искал. Это фрагменты кода для добавления анимации изображений в 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;
}
Ответ 7
Это, я думаю, самый короткий способ сделать это. Создайте анимацию UIView и зафиксируйте ее на вашем изображении.
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[myImageView setAlpha:0.0];
[UIView commitAnimations];
Ответ 8
Используя свойство 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)
Ответ 9
После игры с UIView.transition()
и получения проблем с опцией .transitionCrossDissolve
(я пытался анимировать изменения изображений внутри одного UIImageView и переход происходил мгновенно без анимации), я обнаружил, что вам просто нужно добавить еще одну опцию, которая позволяет вам свойства анимации, изменяющиеся внутри вида (Swift 4.2):
UIView.transition(with: self.imageView,
duration: 1,
options: [.allowAnimatedContent, .transitionCrossDissolve],
animations: { self.imageView.image = newImage },
completion: nil)
Кроме того: если у вас есть какие-либо подпредставления в вашем imageView, они также будут перерисованы и могут помешать анимации. Например, у меня было подпредставление с размытием на моем imageView, и в этом случае анимация не работает. Поэтому я просто изменил свою иерархию представлений и переместил размытие в его собственное представление и поместил его поверх imageView.