Skip to content

Remove the WebImage placeholder maxWidth/maxHeight modifier, this may break some use case like TabView. If user want to use placeholder, limit themselves #178

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 44 additions & 23 deletions SDWebImageSwiftUI/Classes/ImagePlayer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,22 @@ public final class ImagePlayer : ObservableObject {
/// Current playing frame image
@Published public var currentFrame: PlatformImage?

/// Current playing frame index
@Published public var currentFrameIndex: UInt = 0

/// Current playing loop count
@Published public var currentLoopCount: UInt = 0

/// Whether current player is valid for playing. This will check the internal player exist or not
public var isValid: Bool {
player != nil
}

/// Current playing status
public var isPlaying: Bool {
player?.isPlaying ?? false
}

/// Start the animation
public func startPlaying() {
player?.startPlaying()
Expand All @@ -52,38 +68,43 @@ public final class ImagePlayer : ObservableObject {
player?.stopPlaying()
}

/// Seek to frame and loop count
public func seekToFrame(at: UInt, loopCount: UInt) {
player?.seekToFrame(at: at, loopCount: loopCount)
}

/// Clear the frame buffer
public func clearFrameBuffer() {
player?.clearFrameBuffer()
}


/// Setup the player using Animated Image
/// Setup the player using Animated Image.
/// After setup, you can always check `isValid` status, or call `startPlaying` to play the animation.
/// - Parameter image: animated image
public func setupPlayer(image: PlatformImage?) {
if player != nil {
public func setupPlayer(animatedImage: SDAnimatedImageProvider) {
if isValid {
return
}
if let animatedImage = image as? SDAnimatedImageProvider & PlatformImage {
if let imagePlayer = SDAnimatedImagePlayer(provider: animatedImage) {
imagePlayer.animationFrameHandler = { [weak self] (_, frame) in
self?.currentFrame = frame
}
// Setup configuration
if let maxBufferSize = maxBufferSize {
imagePlayer.maxBufferSize = maxBufferSize
}
if let customLoopCount = customLoopCount {
imagePlayer.totalLoopCount = customLoopCount
}
imagePlayer.runLoopMode = runLoopMode
imagePlayer.playbackRate = playbackRate
imagePlayer.playbackMode = playbackMode

self.player = imagePlayer

imagePlayer.startPlaying()
if let imagePlayer = SDAnimatedImagePlayer(provider: animatedImage) {
imagePlayer.animationFrameHandler = { [weak self] (index, frame) in
self?.currentFrameIndex = index
self?.currentFrame = frame
}
imagePlayer.animationLoopHandler = { [weak self] (loopCount) in
self?.currentLoopCount = loopCount
}
// Setup configuration
if let maxBufferSize = maxBufferSize {
imagePlayer.maxBufferSize = maxBufferSize
}
if let customLoopCount = customLoopCount {
imagePlayer.totalLoopCount = customLoopCount
}
imagePlayer.runLoopMode = runLoopMode
imagePlayer.playbackRate = playbackRate
imagePlayer.playbackMode = playbackMode

self.player = imagePlayer
}
}
}
58 changes: 31 additions & 27 deletions SDWebImageSwiftUI/Classes/WebImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public struct WebImage : View {
var placeholder: AnyView?
var retryOnAppear: Bool = true
var cancelOnDisappear: Bool = true
var pausable: Bool = true
var purgeable: Bool = false

@ObservedObject var imageManager: ImageManager

Expand All @@ -26,9 +28,6 @@ public struct WebImage : View {

@ObservedObject var imagePlayer: ImagePlayer

var pausable: Bool = true
var purgeable: Bool = false

/// Create a web image with url, placeholder, custom options and context.
/// - Parameter url: The image url
/// - Parameter options: The options to use when downloading the image. See `SDWebImageOptions` for the possible values.
Expand Down Expand Up @@ -61,38 +60,30 @@ public struct WebImage : View {
imageManager.load()
}
return Group {
if imageManager.image != nil {
if let image = imageManager.image {
if isAnimating && !imageManager.isIncremental {
if imagePlayer.currentFrame != nil {
configure(image: imagePlayer.currentFrame!)
.onPlatformAppear(appear: {
self.imagePlayer.startPlaying()
}, disappear: {
if self.pausable {
self.imagePlayer.pausePlaying()
} else {
self.imagePlayer.stopPlaying()
}
if self.purgeable {
self.imagePlayer.clearFrameBuffer()
}
})
} else {
configure(image: imageManager.image!)
.onReceive(imageManager.$image) { image in
self.imagePlayer.setupPlayer(image: image)
setupPlayer()
.onPlatformAppear(appear: {
self.imagePlayer.startPlaying()
}, disappear: {
if self.pausable {
self.imagePlayer.pausePlaying()
} else {
self.imagePlayer.stopPlaying()
}
}
if self.purgeable {
self.imagePlayer.clearFrameBuffer()
}
})
} else {
if imagePlayer.currentFrame != nil {
configure(image: imagePlayer.currentFrame!)
if let currentFrame = imagePlayer.currentFrame {
configure(image: currentFrame)
} else {
configure(image: imageManager.image!)
configure(image: image)
}
}
} else {
setupPlaceholder()
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
.onPlatformAppear(appear: {
// Load remote image when first appear
if self.imageManager.isFirstLoad {
Expand Down Expand Up @@ -164,6 +155,19 @@ public struct WebImage : View {
}
}

/// Animated Image Support
func setupPlayer() -> some View {
if let currentFrame = imagePlayer.currentFrame {
return configure(image: currentFrame)
} else {
if let animatedImage = imageManager.image as? SDAnimatedImageProvider {
self.imagePlayer.setupPlayer(animatedImage: animatedImage)
self.imagePlayer.startPlaying()
}
return configure(image: imageManager.image!)
}
}

/// Placeholder View Support
func setupPlaceholder() -> some View {
// Don't use `Group` because it will trigger `.onAppear` and `.onDisappear` when condition view removed, treat placeholder as an entire component
Expand Down