|
@@ -1,6 +1,6 @@
|
|
//
|
|
//
|
|
// YYAnimatedImageView.m
|
|
// YYAnimatedImageView.m
|
|
-// YYKit <https://github.com/ibireme/YYKit>
|
|
|
|
|
|
+// YYImage <https://github.com/ibireme/YYImage>
|
|
//
|
|
//
|
|
// Created by ibireme on 14/10/19.
|
|
// Created by ibireme on 14/10/19.
|
|
// Copyright (c) 2015 ibireme.
|
|
// Copyright (c) 2015 ibireme.
|
|
@@ -12,19 +12,18 @@
|
|
#import "YYAnimatedImageView.h"
|
|
#import "YYAnimatedImageView.h"
|
|
#import "YYImageCoder.h"
|
|
#import "YYImageCoder.h"
|
|
#import <pthread.h>
|
|
#import <pthread.h>
|
|
-#import <libkern/OSAtomic.h>
|
|
|
|
#import <mach/mach.h>
|
|
#import <mach/mach.h>
|
|
|
|
|
|
|
|
|
|
#define BUFFER_SIZE (10 * 1024 * 1024) // 10MB (minimum memory buffer size)
|
|
#define BUFFER_SIZE (10 * 1024 * 1024) // 10MB (minimum memory buffer size)
|
|
|
|
|
|
-#define LOCK(...) OSSpinLockLock(&self->_lock); \
|
|
|
|
|
|
+#define LOCK(...) dispatch_semaphore_wait(self->_lock, DISPATCH_TIME_FOREVER); \
|
|
__VA_ARGS__; \
|
|
__VA_ARGS__; \
|
|
-OSSpinLockUnlock(&self->_lock);
|
|
|
|
|
|
+dispatch_semaphore_signal(self->_lock);
|
|
|
|
|
|
-#define LOCK_VIEW(...) OSSpinLockLock(&view->_lock); \
|
|
|
|
|
|
+#define LOCK_VIEW(...) dispatch_semaphore_wait(view->_lock, DISPATCH_TIME_FOREVER); \
|
|
__VA_ARGS__; \
|
|
__VA_ARGS__; \
|
|
-OSSpinLockUnlock(&view->_lock);
|
|
|
|
|
|
+dispatch_semaphore_signal(view->_lock);
|
|
|
|
|
|
|
|
|
|
static int64_t _YYDeviceMemoryTotal() {
|
|
static int64_t _YYDeviceMemoryTotal() {
|
|
@@ -113,12 +112,12 @@ static int64_t _YYDeviceMemoryFree() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-typedef NS_ENUM(NSUInteger, YYAnimagedImageType) {
|
|
|
|
- YYAnimagedImageTypeNone = 0,
|
|
|
|
- YYAnimagedImageTypeImage,
|
|
|
|
- YYAnimagedImageTypeHighlightedImage,
|
|
|
|
- YYAnimagedImageTypeImages,
|
|
|
|
- YYAnimagedImageTypeHighlightedImages,
|
|
|
|
|
|
+typedef NS_ENUM(NSUInteger, YYAnimatedImageType) {
|
|
|
|
+ YYAnimatedImageTypeNone = 0,
|
|
|
|
+ YYAnimatedImageTypeImage,
|
|
|
|
+ YYAnimatedImageTypeHighlightedImage,
|
|
|
|
+ YYAnimatedImageTypeImages,
|
|
|
|
+ YYAnimatedImageTypeHighlightedImages,
|
|
};
|
|
};
|
|
|
|
|
|
@interface YYAnimatedImageView() {
|
|
@interface YYAnimatedImageView() {
|
|
@@ -126,7 +125,7 @@ typedef NS_ENUM(NSUInteger, YYAnimagedImageType) {
|
|
UIImage <YYAnimatedImage> *_curAnimatedImage;
|
|
UIImage <YYAnimatedImage> *_curAnimatedImage;
|
|
|
|
|
|
dispatch_once_t _onceToken;
|
|
dispatch_once_t _onceToken;
|
|
- OSSpinLock _lock; ///< lock for _buffer
|
|
|
|
|
|
+ dispatch_semaphore_t _lock; ///< lock for _buffer
|
|
NSOperationQueue *_requestQueue; ///< image request queue, serial
|
|
NSOperationQueue *_requestQueue; ///< image request queue, serial
|
|
|
|
|
|
CADisplayLink *_link; ///< ticker for change frame
|
|
CADisplayLink *_link; ///< ticker for change frame
|
|
@@ -197,6 +196,13 @@ typedef NS_ENUM(NSUInteger, YYAnimagedImageType) {
|
|
return self;
|
|
return self;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+- (instancetype)initWithFrame:(CGRect)frame {
|
|
|
|
+ self = [super initWithFrame:frame];
|
|
|
|
+ _runloopMode = NSRunLoopCommonModes;
|
|
|
|
+ _autoPlayAnimatedImage = YES;
|
|
|
|
+ return self;
|
|
|
|
+}
|
|
|
|
+
|
|
- (instancetype)initWithImage:(UIImage *)image {
|
|
- (instancetype)initWithImage:(UIImage *)image {
|
|
self = [super init];
|
|
self = [super init];
|
|
_runloopMode = NSRunLoopCommonModes;
|
|
_runloopMode = NSRunLoopCommonModes;
|
|
@@ -220,7 +226,7 @@ typedef NS_ENUM(NSUInteger, YYAnimagedImageType) {
|
|
// init the animated params.
|
|
// init the animated params.
|
|
- (void)resetAnimated {
|
|
- (void)resetAnimated {
|
|
dispatch_once(&_onceToken, ^{
|
|
dispatch_once(&_onceToken, ^{
|
|
- _lock = OS_SPINLOCK_INIT;
|
|
|
|
|
|
+ _lock = dispatch_semaphore_create(1);
|
|
_buffer = [NSMutableDictionary new];
|
|
_buffer = [NSMutableDictionary new];
|
|
_requestQueue = [[NSOperationQueue alloc] init];
|
|
_requestQueue = [[NSOperationQueue alloc] init];
|
|
_requestQueue.maxConcurrentOperationCount = 1;
|
|
_requestQueue.maxConcurrentOperationCount = 1;
|
|
@@ -265,22 +271,22 @@ typedef NS_ENUM(NSUInteger, YYAnimagedImageType) {
|
|
|
|
|
|
- (void)setImage:(UIImage *)image {
|
|
- (void)setImage:(UIImage *)image {
|
|
if (self.image == image) return;
|
|
if (self.image == image) return;
|
|
- [self setImage:image withType:YYAnimagedImageTypeImage];
|
|
|
|
|
|
+ [self setImage:image withType:YYAnimatedImageTypeImage];
|
|
}
|
|
}
|
|
|
|
|
|
- (void)setHighlightedImage:(UIImage *)highlightedImage {
|
|
- (void)setHighlightedImage:(UIImage *)highlightedImage {
|
|
if (self.highlightedImage == highlightedImage) return;
|
|
if (self.highlightedImage == highlightedImage) return;
|
|
- [self setImage:highlightedImage withType:YYAnimagedImageTypeHighlightedImage];
|
|
|
|
|
|
+ [self setImage:highlightedImage withType:YYAnimatedImageTypeHighlightedImage];
|
|
}
|
|
}
|
|
|
|
|
|
- (void)setAnimationImages:(NSArray *)animationImages {
|
|
- (void)setAnimationImages:(NSArray *)animationImages {
|
|
if (self.animationImages == animationImages) return;
|
|
if (self.animationImages == animationImages) return;
|
|
- [self setImage:animationImages withType:YYAnimagedImageTypeImages];
|
|
|
|
|
|
+ [self setImage:animationImages withType:YYAnimatedImageTypeImages];
|
|
}
|
|
}
|
|
|
|
|
|
- (void)setHighlightedAnimationImages:(NSArray *)highlightedAnimationImages {
|
|
- (void)setHighlightedAnimationImages:(NSArray *)highlightedAnimationImages {
|
|
if (self.highlightedAnimationImages == highlightedAnimationImages) return;
|
|
if (self.highlightedAnimationImages == highlightedAnimationImages) return;
|
|
- [self setImage:highlightedAnimationImages withType:YYAnimagedImageTypeHighlightedImages];
|
|
|
|
|
|
+ [self setImage:highlightedAnimationImages withType:YYAnimatedImageTypeHighlightedImages];
|
|
}
|
|
}
|
|
|
|
|
|
- (void)setHighlighted:(BOOL)highlighted {
|
|
- (void)setHighlighted:(BOOL)highlighted {
|
|
@@ -289,46 +295,46 @@ typedef NS_ENUM(NSUInteger, YYAnimagedImageType) {
|
|
[self imageChanged];
|
|
[self imageChanged];
|
|
}
|
|
}
|
|
|
|
|
|
-- (id)imageForType:(YYAnimagedImageType)type {
|
|
|
|
|
|
+- (id)imageForType:(YYAnimatedImageType)type {
|
|
switch (type) {
|
|
switch (type) {
|
|
- case YYAnimagedImageTypeNone: return nil;
|
|
|
|
- case YYAnimagedImageTypeImage: return self.image;
|
|
|
|
- case YYAnimagedImageTypeHighlightedImage: return self.highlightedImage;
|
|
|
|
- case YYAnimagedImageTypeImages: return self.animationImages;
|
|
|
|
- case YYAnimagedImageTypeHighlightedImages: return self.highlightedAnimationImages;
|
|
|
|
|
|
+ case YYAnimatedImageTypeNone: return nil;
|
|
|
|
+ case YYAnimatedImageTypeImage: return self.image;
|
|
|
|
+ case YYAnimatedImageTypeHighlightedImage: return self.highlightedImage;
|
|
|
|
+ case YYAnimatedImageTypeImages: return self.animationImages;
|
|
|
|
+ case YYAnimatedImageTypeHighlightedImages: return self.highlightedAnimationImages;
|
|
}
|
|
}
|
|
return nil;
|
|
return nil;
|
|
}
|
|
}
|
|
|
|
|
|
-- (YYAnimagedImageType)currentImageType {
|
|
|
|
- YYAnimagedImageType curType = YYAnimagedImageTypeNone;
|
|
|
|
|
|
+- (YYAnimatedImageType)currentImageType {
|
|
|
|
+ YYAnimatedImageType curType = YYAnimatedImageTypeNone;
|
|
if (self.highlighted) {
|
|
if (self.highlighted) {
|
|
- if (self.highlightedAnimationImages.count) curType = YYAnimagedImageTypeHighlightedImages;
|
|
|
|
- else if (self.highlightedImage) curType = YYAnimagedImageTypeHighlightedImage;
|
|
|
|
|
|
+ if (self.highlightedAnimationImages.count) curType = YYAnimatedImageTypeHighlightedImages;
|
|
|
|
+ else if (self.highlightedImage) curType = YYAnimatedImageTypeHighlightedImage;
|
|
}
|
|
}
|
|
- if (curType == YYAnimagedImageTypeNone) {
|
|
|
|
- if (self.animationImages.count) curType = YYAnimagedImageTypeImages;
|
|
|
|
- else if (self.image) curType = YYAnimagedImageTypeImage;
|
|
|
|
|
|
+ if (curType == YYAnimatedImageTypeNone) {
|
|
|
|
+ if (self.animationImages.count) curType = YYAnimatedImageTypeImages;
|
|
|
|
+ else if (self.image) curType = YYAnimatedImageTypeImage;
|
|
}
|
|
}
|
|
return curType;
|
|
return curType;
|
|
}
|
|
}
|
|
|
|
|
|
-- (void)setImage:(id)image withType:(YYAnimagedImageType)type {
|
|
|
|
|
|
+- (void)setImage:(id)image withType:(YYAnimatedImageType)type {
|
|
[self stopAnimating];
|
|
[self stopAnimating];
|
|
if (_link) [self resetAnimated];
|
|
if (_link) [self resetAnimated];
|
|
_curFrame = nil;
|
|
_curFrame = nil;
|
|
switch (type) {
|
|
switch (type) {
|
|
- case YYAnimagedImageTypeNone: break;
|
|
|
|
- case YYAnimagedImageTypeImage: super.image = image; break;
|
|
|
|
- case YYAnimagedImageTypeHighlightedImage: super.highlightedImage = image; break;
|
|
|
|
- case YYAnimagedImageTypeImages: super.animationImages = image; break;
|
|
|
|
- case YYAnimagedImageTypeHighlightedImages: super.highlightedAnimationImages = image; break;
|
|
|
|
|
|
+ case YYAnimatedImageTypeNone: break;
|
|
|
|
+ case YYAnimatedImageTypeImage: super.image = image; break;
|
|
|
|
+ case YYAnimatedImageTypeHighlightedImage: super.highlightedImage = image; break;
|
|
|
|
+ case YYAnimatedImageTypeImages: super.animationImages = image; break;
|
|
|
|
+ case YYAnimatedImageTypeHighlightedImages: super.highlightedAnimationImages = image; break;
|
|
}
|
|
}
|
|
[self imageChanged];
|
|
[self imageChanged];
|
|
}
|
|
}
|
|
|
|
|
|
- (void)imageChanged {
|
|
- (void)imageChanged {
|
|
- YYAnimagedImageType newType = [self currentImageType];
|
|
|
|
|
|
+ YYAnimatedImageType newType = [self currentImageType];
|
|
id newVisibleImage = [self imageForType:newType];
|
|
id newVisibleImage = [self imageForType:newType];
|
|
NSUInteger newImageFrameCount = 0;
|
|
NSUInteger newImageFrameCount = 0;
|
|
BOOL hasContentsRect = NO;
|
|
BOOL hasContentsRect = NO;
|
|
@@ -397,8 +403,8 @@ typedef NS_ENUM(NSUInteger, YYAnimagedImageType) {
|
|
}
|
|
}
|
|
|
|
|
|
- (void)startAnimating {
|
|
- (void)startAnimating {
|
|
- YYAnimagedImageType type = [self currentImageType];
|
|
|
|
- if (type == YYAnimagedImageTypeImages || type == YYAnimagedImageTypeHighlightedImages) {
|
|
|
|
|
|
+ YYAnimatedImageType type = [self currentImageType];
|
|
|
|
+ if (type == YYAnimatedImageTypeImages || type == YYAnimatedImageTypeHighlightedImages) {
|
|
NSArray *images = [self imageForType:type];
|
|
NSArray *images = [self imageForType:type];
|
|
if (images.count > 0) {
|
|
if (images.count > 0) {
|
|
[super startAnimating];
|
|
[super startAnimating];
|
|
@@ -620,17 +626,21 @@ typedef NS_ENUM(NSUInteger, YYAnimagedImageType) {
|
|
self = [super initWithCoder:aDecoder];
|
|
self = [super initWithCoder:aDecoder];
|
|
_runloopMode = [aDecoder decodeObjectForKey:@"runloopMode"];
|
|
_runloopMode = [aDecoder decodeObjectForKey:@"runloopMode"];
|
|
if (_runloopMode.length == 0) _runloopMode = NSRunLoopCommonModes;
|
|
if (_runloopMode.length == 0) _runloopMode = NSRunLoopCommonModes;
|
|
- _autoPlayAnimatedImage = [aDecoder decodeBoolForKey:@"autoPlayAnimatedImage"];
|
|
|
|
|
|
+ if ([aDecoder containsValueForKey:@"autoPlayAnimatedImage"]) {
|
|
|
|
+ _autoPlayAnimatedImage = [aDecoder decodeBoolForKey:@"autoPlayAnimatedImage"];
|
|
|
|
+ } else {
|
|
|
|
+ _autoPlayAnimatedImage = YES;
|
|
|
|
+ }
|
|
|
|
|
|
UIImage *image = [aDecoder decodeObjectForKey:@"YYAnimatedImage"];
|
|
UIImage *image = [aDecoder decodeObjectForKey:@"YYAnimatedImage"];
|
|
UIImage *highlightedImage = [aDecoder decodeObjectForKey:@"YYHighlightedAnimatedImage"];
|
|
UIImage *highlightedImage = [aDecoder decodeObjectForKey:@"YYHighlightedAnimatedImage"];
|
|
if (image) {
|
|
if (image) {
|
|
self.image = image;
|
|
self.image = image;
|
|
- [self setImage:image withType:YYAnimagedImageTypeImage];
|
|
|
|
|
|
+ [self setImage:image withType:YYAnimatedImageTypeImage];
|
|
}
|
|
}
|
|
if (highlightedImage) {
|
|
if (highlightedImage) {
|
|
self.highlightedImage = highlightedImage;
|
|
self.highlightedImage = highlightedImage;
|
|
- [self setImage:highlightedImage withType:YYAnimagedImageTypeHighlightedImage];
|
|
|
|
|
|
+ [self setImage:highlightedImage withType:YYAnimatedImageTypeHighlightedImage];
|
|
}
|
|
}
|
|
return self;
|
|
return self;
|
|
}
|
|
}
|