Add the advanced control on SDAnimatedImageView/Player
This commit is contained in:
parent
3c9c30c282
commit
09f2f74da8
|
@ -64,6 +64,10 @@ public struct AnimatedImage : PlatformViewRepresentable {
|
|||
var incrementalLoad: Bool?
|
||||
var maxBufferSize: UInt?
|
||||
var customLoopCount: Int?
|
||||
var runLoopMode: RunLoop.Mode?
|
||||
var pausable: Bool?
|
||||
var clearBufferWhenStopped: Bool?
|
||||
var playBackRate: Double?
|
||||
#if os(macOS) || os(iOS) || os(tvOS)
|
||||
// These configurations only useful for web image loading
|
||||
var indicator: SDWebImageIndicator?
|
||||
|
@ -467,12 +471,40 @@ public struct AnimatedImage : PlatformViewRepresentable {
|
|||
}
|
||||
#elseif os(watchOS)
|
||||
if let customLoopCount = self.customLoopCount {
|
||||
view.wrapped.setAnimationRepeatCount(customLoopCount as NSNumber)
|
||||
view.wrapped.animationRepeatCount = customLoopCount as NSNumber
|
||||
} else {
|
||||
// disable custom loop count
|
||||
view.wrapped.setAnimationRepeatCount(nil)
|
||||
view.wrapped.animationRepeatCount = nil
|
||||
}
|
||||
#endif
|
||||
|
||||
// RunLoop Mode
|
||||
if let runLoopMode = self.runLoopMode {
|
||||
view.wrapped.runLoopMode = runLoopMode
|
||||
} else {
|
||||
view.wrapped.runLoopMode = .common
|
||||
}
|
||||
|
||||
// Pausable
|
||||
if let pausable = self.pausable {
|
||||
view.wrapped.resetFrameIndexWhenStopped = !pausable
|
||||
} else {
|
||||
view.wrapped.resetFrameIndexWhenStopped = false
|
||||
}
|
||||
|
||||
// Clear Buffer
|
||||
if let clearBufferWhenStopped = self.clearBufferWhenStopped {
|
||||
view.wrapped.clearBufferWhenStopped = clearBufferWhenStopped
|
||||
} else {
|
||||
view.wrapped.clearBufferWhenStopped = false
|
||||
}
|
||||
|
||||
// Playback Rate
|
||||
if let playBackRate = self.playBackRate {
|
||||
view.wrapped.playbackRate = playBackRate
|
||||
} else {
|
||||
view.wrapped.playbackRate = 1.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -625,6 +657,48 @@ extension AnimatedImage {
|
|||
result.incrementalLoad = incrementalLoad
|
||||
return result
|
||||
}
|
||||
|
||||
/// The runLoopMode when animation is playing on. Defaults is `.common`
|
||||
/// You can specify a runloop mode to let it rendering.
|
||||
/// - Note: This is useful for some cases, for example, always specify NSDefaultRunLoopMode, if you want to pause the animation when user scroll (for Mac user, drag the mouse or touchpad)
|
||||
/// - Parameter runLoopMode: The runLoopMode for animation
|
||||
public func runLoopMode(_ runLoopMode: RunLoop.Mode) -> AnimatedImage {
|
||||
var result = self
|
||||
result.runLoopMode = runLoopMode
|
||||
return result
|
||||
}
|
||||
|
||||
/// Whether or not to pause the animation (keep current frame), instead of stop the animation (frame index reset to 0). When the `isAnimating` binding value changed to false.
|
||||
/// Defaults is true.
|
||||
/// - Note: For some of use case, you may want to reset the frame index to 0 when stop, but some other want to keep the current frame index.
|
||||
/// - Parameter pausable: Whether or not to pause the animation instead of stop the animation.
|
||||
public func pausable(_ pausable: Bool) -> AnimatedImage {
|
||||
var result = self
|
||||
result.pausable = pausable
|
||||
return result
|
||||
}
|
||||
|
||||
/// Whether or not to clear frame buffer cache when stopped.
|
||||
/// Note: This is useful when you want to limit the memory usage during frequently visibility changes (such as image view inside a list view, then push and pop)
|
||||
/// - Parameter clearBufferWhenStopped: Whether or not to clear frame buffer cache when stopped.
|
||||
public func clearBufferWhenStopped(_ clearBufferWhenStopped: Bool) -> AnimatedImage {
|
||||
var result = self
|
||||
result.clearBufferWhenStopped = clearBufferWhenStopped
|
||||
return result
|
||||
}
|
||||
|
||||
/// Control the animation playback rate. Default is 1.0.
|
||||
/// `1.0` means the normal speed.
|
||||
/// `0.0` means stopping the animation.
|
||||
/// `0.0-1.0` means the slow speed.
|
||||
/// `> 1.0` means the fast speed.
|
||||
/// `< 0.0` is not supported currently and stop animation. (may support reverse playback in the future)
|
||||
/// - Parameter playBackRate: The animation playback rate.
|
||||
public func playBackRate(_ playBackRate: Double) -> AnimatedImage {
|
||||
var result = self
|
||||
result.playBackRate = playBackRate
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
// Completion Handler
|
||||
|
|
|
@ -15,12 +15,17 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
@interface SDAnimatedImageInterface : WKInterfaceImage
|
||||
|
||||
@property (nonatomic, assign, getter=isAnimating, readonly) BOOL animating;
|
||||
@property (nonatomic, strong, nullable) NSNumber *animationRepeatCount;
|
||||
@property (nonatomic, copy) NSRunLoopMode runLoopMode;
|
||||
@property (nonatomic, assign) BOOL resetFrameIndexWhenStopped;
|
||||
@property (nonatomic, assign) BOOL clearBufferWhenStopped;
|
||||
@property (nonatomic, assign) double playbackRate;
|
||||
|
||||
- (instancetype)init WK_AVAILABLE_WATCHOS_ONLY(6.0);
|
||||
|
||||
/// Set the content mode for image
|
||||
/// @param contentMode The contrent mode
|
||||
- (void)setContentMode:(SDImageScaleMode)contentMode;
|
||||
- (void)setAnimationRepeatCount:(nullable NSNumber *)repeatCount;
|
||||
- (void)setRunLoopMode:(nonnull NSRunLoopMode)runLoopMode;
|
||||
- (void)setPlaybackRate:(double)playbackRate;
|
||||
|
||||
/// Trigger the animation check when view appears/disappears
|
||||
- (void)updateAnimation;
|
||||
|
|
|
@ -54,11 +54,9 @@
|
|||
@property (nonatomic, strong, readwrite) UIImage *currentFrame;
|
||||
@property (nonatomic, assign, readwrite) NSUInteger currentFrameIndex;
|
||||
@property (nonatomic, assign, readwrite) NSUInteger currentLoopCount;
|
||||
@property (nonatomic, strong) NSNumber *animationRepeatCount;
|
||||
@property (nonatomic, assign, getter=isAnimating, readwrite) BOOL animating;
|
||||
@property (nonatomic, assign) BOOL shouldAnimate;
|
||||
@property (nonatomic, copy) NSRunLoopMode runLoopMode;
|
||||
@property (nonatomic, assign) double playbackRate;
|
||||
@property (nonatomic,strong) SDAnimatedImagePlayer *player; // The animation player.
|
||||
@property (nonatomic, strong) SDAnimatedImagePlayer *player; // The animation player.
|
||||
@property (nonatomic) id<CALayerProtocol> imageViewLayer; // The actual rendering layer.
|
||||
|
||||
@end
|
||||
|
@ -162,10 +160,18 @@
|
|||
|
||||
- (void)updateAnimation {
|
||||
[self updateShouldAnimate];
|
||||
if (self.shouldAnimate) {
|
||||
[self startAnimating];
|
||||
} else {
|
||||
[self stopAnimating];
|
||||
if (!self.player) {
|
||||
return;
|
||||
}
|
||||
// Filter automatically animating changes
|
||||
if (self.shouldAnimate && self.isAnimating) {
|
||||
[self.player startPlaying];
|
||||
} else if (!self.shouldAnimate && !self.isAnimating) {
|
||||
if (self.resetFrameIndexWhenStopped) {
|
||||
[self.player stopPlaying];
|
||||
} else {
|
||||
[self.player pausePlaying];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -189,17 +195,8 @@
|
|||
self.shouldAnimate = self.player && isVisible;
|
||||
}
|
||||
|
||||
- (BOOL)isAnimating
|
||||
{
|
||||
if (self.player) {
|
||||
return self.player.isPlaying;
|
||||
} else {
|
||||
id<UIImageViewProtocol> view = (id<UIImageViewProtocol>)[self _interfaceView];
|
||||
return [view isAnimating];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)startAnimating {
|
||||
self.animating = YES;
|
||||
if (self.player) {
|
||||
[self.player startPlaying];
|
||||
} else if (_image.images.count > 0) {
|
||||
|
@ -208,6 +205,7 @@
|
|||
}
|
||||
|
||||
- (void)startAnimatingWithImagesInRange:(NSRange)imageRange duration:(NSTimeInterval)duration repeatCount:(NSInteger)repeatCount {
|
||||
self.animating = YES;
|
||||
if (self.player) {
|
||||
[self.player startPlaying];
|
||||
} else if (_image.images.count > 0) {
|
||||
|
@ -216,8 +214,16 @@
|
|||
}
|
||||
|
||||
- (void)stopAnimating {
|
||||
self.animating = NO;
|
||||
if (self.player) {
|
||||
[self.player stopPlaying];
|
||||
if (self.resetFrameIndexWhenStopped) {
|
||||
[self.player stopPlaying];
|
||||
} else {
|
||||
[self.player pausePlaying];
|
||||
}
|
||||
if (self.clearBufferWhenStopped) {
|
||||
[self.player clearFrameBuffer];
|
||||
}
|
||||
} else if (_image.images.count > 0) {
|
||||
[super stopAnimating];
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue