Анимация с использованием массива изображений в последовательности

У меня есть массив изображений, которые я хочу оживить, играя эти изображения один за другим в последовательности. Я хочу повторить весь цикл несколько раз. Я разрабатываю игру для iPad. Предложите мне метод достижения этой функциональности в Objective-C с каркасом Cocoa.

5 Solutions collect form web for “Анимация с использованием массива изображений в последовательности”

См. Свойство animationImages UIImageView . Трудно сказать, соответствует ли это вашим потребностям, поскольку вы не даете нам подробностей, но это хорошее начало.

 NSArray *animationArray = [NSArray arrayWithObjects: [UIImage imageNamed:@"images.jpg"], [UIImage imageNamed:@"images1.jpg"], [UIImage imageNamed:@"images5.jpg"], [UIImage imageNamed:@"index3.jpg"], nil]; UIImageView *animationView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0,320, 460)]; animationView.backgroundColor = [UIColor purpleColor]; animationView.animationImages = animationArray; animationView.animationDuration = 1.5; animationView.animationRepeatCount = 0; [animationView startAnimating]; [self.view addSubview:animationView]; [animationView release]; 

добавьте свои собственные изображения в массив.repeat Count 0 означает бесконечный цикл. Вы также можете указать свой собственный номер.

Существует как минимум 3 способа анимации массива изображений через UIImageView . Я добавляю 3 ссылки, чтобы загрузить образец кода для трех возможностей.

Первый – это тот, который все знают. Другие менее известны.

– UIImageView.animationImages
Пример ссылки

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

Точно так же нет возможности автоматически сохранить последнее изображение из анимации в UIImageView . Если мы объединим обе проблемы, у нас может быть пробел в конце анимации, если мы хотим сохранить последний кадр на экране.

 self.imageView.animationImages = self.imagesArray; // the array with the images self.imageView.animationDuration = kAnimationDuration; // static const with your value self.imageView.animationRepeatCount = 1; [self.imageView startAnimating]; 

– CAKeyframeAnimation
Пример ссылки

Этот способ анимации работает через CAAnimation . У него есть удобный делегат для использования, и мы можем знать, когда закончится анимация.

Вероятно, это лучший способ анимации массива изображений.

 - (void)animateImages { CAKeyframeAnimation *keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"contents"]; keyframeAnimation.values = self.imagesArray; keyframeAnimation.repeatCount = 1.0f; keyframeAnimation.duration = kAnimationDuration; // static const with your value keyframeAnimation.delegate = self; // keyframeAnimation.removedOnCompletion = YES; keyframeAnimation.removedOnCompletion = NO; keyframeAnimation.fillMode = kCAFillModeForwards; CALayer *layer = self.animationImageView.layer; [layer addAnimation:keyframeAnimation forKey:@"girlAnimation"]; } 

Делегат:

 - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { if (flag) { // your code } } 

– CADisplayLink
Пример ссылки

A CADisplayLink object is a timer object that allows your application to synchronize its drawing to the refresh rate of the display.

Этот способ сделать это действительно интересен и открывает множество возможностей манипулировать тем, что мы показываем на экране.

Отображаемый getLink:

 - (CADisplayLink *)displayLink { if (!_displayLink) { _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(linkProgress)]; } return _displayLink; } 

Методы:

 - (void)animateImages { self.displayLink.frameInterval = 5; self.frameNumber = 0; [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; } - (void)linkProgress { if (self.frameNumber > 16) { [self.displayLink invalidate]; self.displayLink = nil; self.animationImageView.image = [UIImage imageNamed:@"lastImageName"]; self.imagesArray = nil; return; } self.animationImageView.image = self.imagesArray[self.frameNumber++]; self.frameNumber++; } 

ОБЩАЯ ПРОБЛЕМА:

Несмотря на то, что у нас есть три возможности, если ваша анимация имеет много больших изображений, подумайте об использовании видео. Использование памяти значительно уменьшится.

Общая проблема, с которой вам придется столкнуться, – это момент выделения изображений.

Если вы используете [UIImage imageNamed: @ "imageName"], у вас возникнут проблемы.

От Apple:

This method looks in the system caches for an image object with the specified name and returns that object if it exists. If a matching image object is not already in the cache, this method locates and loads the image data from disk or asset catelog, and then returns the resulting object. You can not assume that this method is thread safe.

Итак, imageNamed: сохраняет изображение в приватном кэше.
– Первая проблема заключается в том, что вы не можете контролировать размер кеша.
– Вторая проблема заключается в том, что кеш не очищался вовремя, и если вы выделяете много изображений с помощью imageNamed: ваше приложение, вероятно, выйдет из imageNamed: .

РЕШЕНИЕ:

Выделите изображения непосредственно из Bundle :

 NSString *imageName = [NSString stringWithFormat:@"imageName.png"]; NSString *path = [[NSBundle mainBundle] pathForResource:imageName // Allocating images with imageWithContentsOfFile makes images to do not cache. UIImage *image = [UIImage imageWithContentsOfFile:path]; 

Небольшая проблема:

Изображения в Images.xcassets никогда не выделяются. Таким образом, перемещайте изображения вне Images.xcassets чтобы выделить их прямо из Bundle.

Лучшее решение для меня использует CADisplayLink. UIImageView не имеет блока завершения, и вы не можете поймать шаги анимации. В моей задаче я должен постепенно менять фон представления с помощью секвенсора изображений. Таким образом CADisplayLink позволяет обрабатывать шаги и завершать анимацию. Если мы говорим об использовании памяти, я думаю, что лучшее решение загружает изображения из набора и удаления массива после завершения

ImageSequencer.h

 typedef void (^Block)(void); @protocol ImageSequencerDelegate; @interface QSImageSequencer : UIImageView @property (nonatomic, weak) id <ImageSequencerDelegate> delegate; - (void)startAnimatingWithCompletionBlock:(Block)block; @end @protocol ImageSequencerDelegate <NSObject> @optional - (void)animationDidStart; - (void)animationDidStop; - (void)didChangeImage:(UIImage *)image; @end 

ImageSequencer.m

 - (instancetype)init { if (self = [super init]) { _imagesArray = [NSMutableArray array]; self.image = [self.imagesArray firstObject]; } return self; } #pragma mark - Animation - (void)startAnimating { [self startAnimatingWithCompletionBlock:nil]; } - (void)startAnimatingWithCompletionBlock:(Block)block { self.frameNumber = 0; [self setSuccessBlock:block]; self.displayLink.frameInterval = 5; if (self.delegate && [self.delegate respondsToSelector:@selector(animationDidStart)]) { [self.delegate animationDidStart]; } [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; } -(void)stopAnimating { self.image = [self.imagesArray lastObject]; [self.displayLink invalidate]; [self setDisplayLink:nil]; Block block_ = [self successBlock]; if (block_) { block_(); } if (self.delegate && [self.delegate respondsToSelector:@selector(animationDidStop)]) { [self.delegate animationDidStop]; } [self.imagesArray removeAllObjects]; } - (void)animationProgress { if (self.frameNumber >= self.imagesArray.count) { [self stopAnimating]; return; } if (self.delegate && [self.delegate respondsToSelector:@selector(didChangeImage:)]) { [self.delegate didChangeImage:self.imagesArray[self.frameNumber]]; } self.image = self.imagesArray[self.frameNumber]; self.frameNumber++; } #pragma mark - Getters / Setters - (CADisplayLink *)displayLink { if (!_displayLink){ _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(animationProgress)]; } return _displayLink; } - (NSMutableArray<UIImage *> *)imagesArray { if (_imagesArray.count == 0) { // get images from bundle and set to array } return _imagesArray; } @end 

Я добавил расширение версии 3.0 для этого

 extension UIImageView { func animate(images: [UIImage], index: Int = 0, completionHandler: (() -> Void)?) { UIView.transition(with: self, duration: 0.5, options: .transitionCrossDissolve, animations: { self.image = images[index] }, completion: { value in let idx = index == images.count-1 ? 0 : index+1 if idx == 0 { completionHandler!() } else { self.animate(images: images, index: idx, completionHandler: completionHandler) } }) } } 
  • Отключить жестов для перехода по экрану в UITableView
  • Изменение цвета текста кнопки при выборе
  • Приложение iOS 10 разбилось, поскольку оно пыталось получить доступ к конфиденциальным данным
  • Как сделать прозрачный фон см. На главном экране?
  • Предупреждение о блокировке элемента под управлением версии (Xcode 4)
  • Отображение UIAlertView через некоторое время
  • Показывает оповещение с помощью Cocoa
  • NSDate не возвращает правильную дату
  • Преобразование адреса в долготу и широту
  • CoreDataGeneratedAccessors для удаления объекта, похоже, не удаляют
  • NSSortDescriptor - сортировать дескриптор на основе другого массива
  • Interesting Posts

    Сохранение изображения в библиотеке фотографий и получение URL-адреса сохраненного изображения

    Как получить информацию из NSData?

    UIActivityIndicator в ячейке UICollectionView случайным образом не скрывает

    Почему push-уведомление отображается, когда приложение находится на переднем плане? (iOS10 / iPhone 7)

    Сопротивление iOS Static vs Dynamic frameworks

    Скрыть клавиатуру при нажатии кнопки поиска на панели поиска, созданной кодом

    Сбой: com.apple.main-thread EXC_BREAKPOINT

    Укажите высоту UIToolbar в раскадровке

    Как создать пользовательский MKAnnotationView и пользовательский заголовок аннотации и субтитры

    Добавить transperant UITableViewCell в конце Groupedtableview без bordercolor

    Невозможно добавить или построить платформу ios в Cordova 5.0.0

    React Native TouchableHighlight игнорирует событие первого клика

    interactivePopGestureRecognizer – pop или back to curent view controller

    Неопределенные символы для архитектуры i386 при добавлении FaceBook Connect

    потянуть, чтобы обновить анимацию, как почта в iOS6

    PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.