Существует как минимум 3 способа анимировать массив изображений с помощью UIImageView
.Я добавляю 3 ссылки для загрузки примера кода для 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.
Этот способ действительно интересен и открываетмножество возможностей манипулировать тем, что мы показываем на экране.
Метод получения DisplayLink:
- (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++;
}
ОБЩАЯ ПРОБЛЕМА:
Несмотря на то, что у нас есть эти 3 возможности, если ваша анимация содержит много больших изображений, рассмотрите возможность использования видео.Использование памяти значительно уменьшится.
Общая проблема, с которой вы столкнетесь при этом, заключается в моменте выделения изображений.
Если вы используете [UIImage imageNamed: @ "imageName"], у вас возникнут проблемы с *. 1061 *
От 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:
, ваше приложение, вероятно, будет зависать.
РЕШЕНИЕ:
Выделите изображения непосредственно из 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.