Как сделать переход между двумя изображениями на iPhone с помощью Core Animation - PullRequest
44 голосов
/ 11 октября 2009

Я делаю это для того, чтобы научиться работать с анимируемыми свойствами Core Animation на iPhone (не для того, чтобы научиться плавно затенять изображения).

Чтение похожих вопросов на SO заставляет меня поверить, что это можно сделать, анимировав свойство .contents слоя UIImageView *1006* примерно так:

UIImage *image1 = [UIImage imageNamed:@"someImage1.png"];
UIImage *image2 = [UIImage imageNamed:@"someImage2.png"];

self.imageView.image = image1;
[self.view addSubview:self.imageView];

CABasicAnimation *crossFade = [CABasicAnimation animationWithKeyPath:@"contents"];
crossFade.duration = 5.0;
self.imageView.layer.contents = image2;
[self.imageView.layer addAnimation:crossFade forKey:@"animateContents"];

Я неправильно понял детали или это невозможно.

Обновление: Приведенный выше код создает пустой UIImageView. Когда я изменяю эту строку:

self.imageView.layer.contents = image2.CGImage;

... Теперь я вижу изображение, но оно не исчезает, оно просто появляется мгновенно.

Ответы [ 6 ]

78 голосов
/ 15 октября 2009

Вы были почти там.

CABasicAnimation *crossFade = [CABasicAnimation animationWithKeyPath:@"contents"];
crossFade.duration = 5.0;
crossFade.fromValue = image1.CGImage;
crossFade.toValue = image2.CGImage;
[self.imageView.layer addAnimation:crossFade forKey:@"animateContents"];

Обратите внимание, что анимация не зависит от фактических значений / содержимого UIImageView. Поэтому вам нужно будет

self.imageView.image = image2;

... чтобы установить конечный результат для вашего изображения.

62 голосов
/ 27 апреля 2012

Я нашел это где-то - это прекрасно работает.

Swift

UIView.transition(with: imageView, duration: 0.33, options: .transitionCrossDissolve, animations: {
      imageView.image = image
}, completion: nil)

ObjC

UIImage * toImage = [UIImage imageNamed:@"image.png"];
[UIView transitionWithView:self.view
                  duration:0.33f
                   options:UIViewAnimationOptionTransitionCrossDissolve
                animations:^{
                    self.imageview.image = toImage;
                } completion:NULL];
20 голосов
/ 09 мая 2012
extension UIImageView
{
    func mySetImage(image:UIImage)
    {
        guard let currentImage = self.image where currentImage != image else { return }
        let animation = CATransition()
        animation.duration = 0.3
        animation.type = kCATransitionFade
        layer.add(animation, forKey: "ImageFade")
        self.image = image
    }
}
1 голос
/ 06 апреля 2015

Быстрое решение

let image1:UIImage = UIImage(named: "someImage1")!;
let image2:UIImage = UIImage(named: "someImage2")!;
let crossFade:CABasicAnimation = CABasicAnimation(keyPath: "contents");
crossFade.duration = 5.0;
crossFade.fromValue = image1.CGImage;
crossFade.toValue = image2.CGImage;
imageView.layer.addAnimation(crossFade, forKey:"animateContents");
1 голос
/ 30 сентября 2014
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.navigationController.navigationBarHidden=false;
UIImage *img=[UIImage imageNamed:@"images.jpeg"];
imgview=[[UIImageView alloc]init];
imgview.frame=CGRectMake(30,90, img.size.width, img.size.height);
[self.view addSubview:imgview];
[self animateImages];
}
- (void)animateImages
{
static int count = 0;
NSArray *animationImages = @[[UIImage imageNamed:@"images.jpeg"], [UIImage imageNamed:@"images (1).jpeg"]];
UIImage *image = [animationImages objectAtIndex:(count % [animationImages count])];

[UIView transitionWithView:imgview
                  duration:2.0f // animation duration
                   options:UIViewAnimationOptionTransitionCrossDissolve
                animations:^{
                    imgview.image = image;
                } completion:^(BOOL finished) {
                    [self animateImages];
                    count++;
                }];

}

0 голосов
/ 11 октября 2009

Мое предложение состояло бы в том, чтобы просто использовать два UIImageView друг над другом. На верхнем изображении находится изображение1, а на нижнем - изображение2:

- (void) crossfade {
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:.5];
    imageView1.alpha = !imageView1.alpha;
    [UIView commitAnimations];
}

Это будет исчезать между двумя изображениями, когда вы его называете. Если вы хотите просто сделать одно затухание и удалить первое изображение после того, как закончите:

- (void) crossfade {
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:.5];
    [UIView setAnimationDelegate:imageView1];
    [UIView setAnimationDidStopSelector:@selector(removeFromSuperview)];
    imageView1.alpha = 0
    [UIView commitAnimations];
}

Edit:

Если вы ищете причину, по которой ваш код не работает, это потому, что вы просто устанавливаете свойство для нового изображения, а затем добавляете бесполезную анимацию. CABasicAnimation имеет fromValue и toValue, которые необходимо установить, затем добавьте эту анимацию в слой, и она должна выполнить анимацию. Не устанавливайте содержимое вручную.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...