Merge pull request #3003 from liulichao123/autoplay

Added autoplay control property to AnimatedImageView (autoPlayAnimatedImage)
This commit is contained in:
DreamPiggy 2020-05-10 15:19:56 +08:00 committed by GitHub
commit a31ba1782f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 96 additions and 27 deletions

View File

@ -81,6 +81,14 @@
*/
@property (nonatomic, assign) BOOL resetFrameIndexWhenStopped;
/**
If the image has more than one frame, set this value to `YES` will automatically
play/stop the animation when the view become visible/invisible.
The default value is `YES`.
*/
@property (nonatomic) BOOL autoPlayAnimatedImage;
/**
You can specify a runloop mode to let it rendering.
Default is NSRunLoopCommonModes on multi-core device, NSDefaultRunLoopMode on single-core device

View File

@ -93,6 +93,7 @@
{
// Pay attention that UIKit's `initWithImage:` will trigger a `setImage:` during initialization before this `commonInit`.
// So the properties which rely on this order, should using lazy-evaluation or do extra check in `setImage:`.
self.autoPlayAnimatedImage = YES;
self.shouldCustomLoopCount = NO;
self.shouldIncrementalLoad = YES;
self.playbackRate = 1.0;
@ -183,8 +184,8 @@
// Ensure disabled highlighting; it's not supported (see `-setHighlighted:`).
super.highlighted = NO;
// Start animating
[self startAnimating];
[self stopAnimating];
[self checkPlay];
[self.imageViewLayer setNeedsDisplay];
}
@ -258,12 +259,7 @@
[super didMoveToSuperview];
#endif
[self updateShouldAnimate];
if (self.shouldAnimate) {
[self startAnimating];
} else {
[self stopAnimating];
}
[self checkPlay];
}
#if SD_MAC
@ -278,12 +274,7 @@
[super didMoveToWindow];
#endif
[self updateShouldAnimate];
if (self.shouldAnimate) {
[self startAnimating];
} else {
[self stopAnimating];
}
[self checkPlay];
}
#if SD_MAC
@ -298,24 +289,14 @@
[super setAlpha:alpha];
#endif
[self updateShouldAnimate];
if (self.shouldAnimate) {
[self startAnimating];
} else {
[self stopAnimating];
}
[self checkPlay];
}
- (void)setHidden:(BOOL)hidden
{
[super setHidden:hidden];
[self updateShouldAnimate];
if (self.shouldAnimate) {
[self startAnimating];
} else {
[self stopAnimating];
}
[self checkPlay];
}
#pragma mark - UIImageView Method Overrides
@ -344,6 +325,8 @@
} else {
#if SD_UIKIT
[super startAnimating];
#else
[super setAnimates:YES];
#endif
}
}
@ -362,6 +345,8 @@
} else {
#if SD_UIKIT
[super stopAnimating];
#else
[super setAnimates:NO];
#endif
}
}
@ -378,9 +363,17 @@
#endif
#if SD_MAC
- (BOOL)animates
{
if (self.player) {
return self.player.isPlaying;
} else {
return [super animates];
}
}
- (void)setAnimates:(BOOL)animates
{
[super setAnimates:animates];
if (animates) {
[self startAnimating];
} else {
@ -403,6 +396,19 @@
#pragma mark - Private Methods
#pragma mark Animation
/// Check if it should be played
- (void)checkPlay
{
if (self.autoPlayAnimatedImage) {
[self updateShouldAnimate];
if (self.shouldAnimate) {
[self startAnimating];
} else {
[self stopAnimating];
}
}
}
// Don't repeatedly check our window & superview in `-displayDidRefresh:` for performance reasons.
// Just update our cached value whenever the animated image or visibility (window, superview, hidden, alpha) is changed.
- (void)updateShouldAnimate

View File

@ -468,6 +468,61 @@ static const NSUInteger kTestGIFFrameCount = 5; // local TestImage.gif loop coun
[self waitForExpectationsWithCommonTimeout];
}
- (void)test28AnimatedImageAutoPlayAnimatedImage {
XCTestExpectation *expectation = [self expectationWithDescription:@"test SDAnimatedImageView AutoPlayAnimatedImage behavior"];
SDAnimatedImageView *imageView = [SDAnimatedImageView new];
imageView.autoPlayAnimatedImage = NO;
#if SD_UIKIT
[self.window addSubview:imageView];
#else
[self.window.contentView addSubview:imageView];
#endif
// This APNG duration is 2s
SDAnimatedImage *image = [SDAnimatedImage imageWithData:[self testAPNGPData]];
imageView.image = image;
#if SD_UIKIT
expect(imageView.animating).equal(NO);
#else
expect(imageView.animates).equal(NO);
#endif
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
#if SD_UIKIT
expect(imageView.animating).equal(NO);
#else
expect(imageView.animates).equal(NO);
#endif
#if SD_UIKIT
[imageView startAnimating];
#else
imageView.animates = YES;
#endif
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
#if SD_UIKIT
expect(imageView.animating).equal(YES);
#else
expect(imageView.animates).equal(YES);
#endif
#if SD_UIKIT
[imageView stopAnimating];
#else
imageView.animates = NO;
#endif
[imageView removeFromSuperview];
[expectation fulfill];
});
[self waitForExpectationsWithCommonTimeout];
}
#pragma mark - Helper
- (UIWindow *)window {
if (!_window) {