Merge pull request #2659 from dreampiggy/bugfix_macOS_animatedImageView

Bugfix macOS related small improvement for SDAnimatedImageView
This commit is contained in:
DreamPiggy 2019-03-31 15:57:40 +08:00 committed by GitHub
commit 47ad8d58d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 15 additions and 26 deletions

View File

@ -61,18 +61,12 @@ static NSUInteger SDDeviceFreeMemory() {
#else #else
@property (nonatomic, strong) CADisplayLink *displayLink; @property (nonatomic, strong) CADisplayLink *displayLink;
#endif #endif
// Layer-backed NSImageView use a subview of `NSImageViewContainerView` to do actual layer rendering. We use this layer instead of `self.layer` during animated image rendering.
#if SD_MAC
@property (nonatomic, strong, readonly) CALayer *imageViewLayer;
#endif
@end @end
@implementation SDAnimatedImageView @implementation SDAnimatedImageView
#if SD_UIKIT #if SD_UIKIT
@dynamic animationRepeatCount; @dynamic animationRepeatCount; // we re-use this property from `UIImageView` super class on iOS.
#else
@dynamic imageViewLayer;
#endif #endif
#pragma mark - Initializers #pragma mark - Initializers
@ -239,20 +233,11 @@ static NSUInteger SDDeviceFreeMemory() {
[self.layer setNeedsDisplay]; [self.layer setNeedsDisplay];
#if SD_MAC #if SD_MAC
[self.layer displayIfNeeded]; // macOS's imageViewLayer is not equal to self.layer. But `[super setImage:]` will impliedly mark it needsDisplay. We call `[self.layer displayIfNeeded]` to immediately refresh the imageViewLayer to avoid flashing [self.layer displayIfNeeded]; // macOS's imageViewLayer may not equal to self.layer. But `[super setImage:]` will impliedly mark it needsDisplay. We call `[self.layer displayIfNeeded]` to immediately refresh the imageViewLayer to avoid flashing
#endif #endif
} }
} }
- (void)setAnimationRepeatCount:(NSInteger)animationRepeatCount
{
#if SD_MAC
_animationRepeatCount = animationRepeatCount;
#else
[super setAnimationRepeatCount:animationRepeatCount];
#endif
}
#if SD_UIKIT #if SD_UIKIT
- (void)setRunLoopMode:(NSString *)runLoopMode - (void)setRunLoopMode:(NSString *)runLoopMode
{ {
@ -287,8 +272,7 @@ static NSUInteger SDDeviceFreeMemory() {
- (CVDisplayLinkRef)displayLink - (CVDisplayLinkRef)displayLink
{ {
if (!_displayLink) { if (!_displayLink) {
CGDirectDisplayID displayID = CGMainDisplayID(); CVReturn error = CVDisplayLinkCreateWithActiveCGDisplays(&_displayLink);
CVReturn error = CVDisplayLinkCreateWithCGDisplay(displayID, &_displayLink);
if (error) { if (error) {
return NULL; return NULL;
} }
@ -312,13 +296,6 @@ static NSUInteger SDDeviceFreeMemory() {
} }
#endif #endif
#if SD_MAC
- (CALayer *)imageViewLayer {
NSView *imageView = objc_getAssociatedObject(self, NSSelectorFromString(@"_imageView"));
return imageView.layer;
}
#endif
#pragma mark - Life Cycle #pragma mark - Life Cycle
- (void)dealloc - (void)dealloc
@ -681,6 +658,18 @@ static NSUInteger SDDeviceFreeMemory() {
} }
#if SD_MAC #if SD_MAC
// Layer-backed NSImageView optionally optimize to use a subview to do actual layer rendering.
// When the optimization is turned on, it calls `updateLayer` instead of `displayLayer:` to update subview's layer.
// When the optimization it turned off, this return nil and calls `displayLayer:` directly.
- (CALayer *)imageViewLayer {
NSView *imageView = imageView = objc_getAssociatedObject(self, NSSelectorFromString(@"_imageView"));
if (!imageView) {
// macOS 10.14
imageView = objc_getAssociatedObject(self, NSSelectorFromString(@"_imageSubview"));
}
return imageView.layer;
}
- (void)updateLayer - (void)updateLayer
{ {
if (_currentFrame) { if (_currentFrame) {