@@ -14,8 +14,8 @@ import SDWebImage
1414final class WebImageModel : ObservableObject {
1515 /// URL image
1616 @Published var url : URL ?
17- @Published var webOptions : SDWebImageOptions = [ ]
18- @Published var webContext : [ SDWebImageContextOption : Any ] ? = nil
17+ @Published var options : SDWebImageOptions = [ ]
18+ @Published var context : [ SDWebImageContextOption : Any ] ? = nil
1919}
2020
2121/// Completion Handler Binding Object, supports dynamic @State changes
@@ -61,11 +61,13 @@ public struct WebImage : View {
6161 /// A observed object to pass through the image configuration to player
6262 @ObservedObject var imageConfiguration = WebImageConfiguration ( )
6363
64+ @ObservedObject var indicatorStatus : IndicatorStatus
65+
6466 // FIXME: Use SwiftUI StateObject and remove onPlatformAppear once drop iOS 13 support
6567 @Backport . StateObject var imagePlayer = ImagePlayer ( )
6668
6769 // FIXME: Use SwiftUI StateObject and remove onPlatformAppear once drop iOS 13 support
68- @Backport . StateObject var imageManager = ImageManager ( )
70+ @Backport . StateObject var imageManager : ImageManager
6971
7072 /// Create a web image with url, placeholder, custom options and context. Optional can support animated image using Binding.
7173 /// - Parameter url: The image url
@@ -83,9 +85,12 @@ public struct WebImage : View {
8385 }
8486 let imageModel = WebImageModel ( )
8587 imageModel. url = url
86- imageModel. webOptions = options
87- imageModel. webContext = context
88+ imageModel. options = options
89+ imageModel. context = context
8890 _imageModel = ObservedObject ( wrappedValue: imageModel)
91+ let imageManager = ImageManager ( )
92+ _imageManager = Backport . StateObject ( wrappedValue: imageManager)
93+ _indicatorStatus = ObservedObject ( wrappedValue: imageManager. indicatorStatus)
8994 }
9095
9196 /// Create a web image with url, placeholder, custom options and context.
@@ -98,7 +103,7 @@ public struct WebImage : View {
98103
99104 public var body : some View {
100105 return Group {
101- if let image = imageManager. image {
106+ if imageManager . image != nil && imageModel . url == imageManager. currentURL {
102107 if isAnimating && !imageManager. isIncremental {
103108 setupPlayer ( )
104109 . onDisappear {
@@ -118,7 +123,7 @@ public struct WebImage : View {
118123 if let currentFrame = imagePlayer. currentFrame {
119124 configure ( image: currentFrame)
120125 } else {
121- configure ( image: image)
126+ configure ( image: imageManager . image! )
122127 }
123128 }
124129 } else {
@@ -127,17 +132,19 @@ public struct WebImage : View {
127132 self . imageManager. successBlock = self . imageHandler. successBlock
128133 self . imageManager. failureBlock = self . imageHandler. failureBlock
129134 self . imageManager. progressBlock = self . imageHandler. progressBlock
130- // Load remote image when first appear
131- self . imageManager. load ( url: imageModel. url, options: imageModel. webOptions, context: imageModel. webContext)
135+ if ( self . imageManager. error == nil ) {
136+ // Load remote image when first appear
137+ self . imageManager. load ( url: imageModel. url, options: imageModel. options, context: imageModel. context)
138+ }
132139 guard self . imageConfiguration. retryOnAppear else { return }
133140 // When using prorgessive loading, the new partial image will cause onAppear. Filter this case
134- if self . imageManager. image = = nil && !self . imageManager. isIncremental {
135- self . imageManager. load ( url: imageModel. url, options: imageModel. webOptions , context: imageModel. webContext )
141+ if self . imageManager. error ! = nil && !self . imageManager. isIncremental {
142+ self . imageManager. load ( url: imageModel. url, options: imageModel. options , context: imageModel. context )
136143 }
137144 } , disappear: {
138145 guard self . imageConfiguration. cancelOnDisappear else { return }
139146 // When using prorgessive loading, the previous partial image will cause onDisappear. Filter this case
140- if self . imageManager. image = = nil && !self . imageManager. isIncremental {
147+ if self . imageManager. error ! = nil && !self . imageManager. isIncremental {
141148 self . imageManager. cancel ( )
142149 }
143150 } )
@@ -196,18 +203,25 @@ public struct WebImage : View {
196203
197204 /// Animated Image Support
198205 func setupPlayer( ) -> some View {
199- if let currentFrame = imagePlayer. currentFrame {
206+ if let currentFrame = imagePlayer. currentFrame, imagePlayer . currentAnimatedImage == imageManager . image! {
200207 return configure ( image: currentFrame) . onAppear {
201208 self . imagePlayer. startPlaying ( )
202209 }
203210 } else {
204211 return configure ( image: imageManager. image!) . onAppear {
205- if let animatedImage = imageManager. image as? SDAnimatedImageProvider {
212+ self . imagePlayer. stopPlaying ( )
213+ if let animatedImage = imageManager. image as? PlatformImage & SDAnimatedImageProvider {
214+ // Clear previous status
215+ self . imagePlayer. player = nil ;
216+ self . imagePlayer. currentFrame = nil ;
217+ self . imagePlayer. currentFrameIndex = 0 ;
218+ self . imagePlayer. currentLoopCount = 0 ;
206219 self . imagePlayer. customLoopCount = self . imageConfiguration. customLoopCount
207220 self . imagePlayer. maxBufferSize = self . imageConfiguration. maxBufferSize
208221 self . imagePlayer. runLoopMode = self . imageConfiguration. runLoopMode
209222 self . imagePlayer. playbackMode = self . imageConfiguration. playbackMode
210223 self . imagePlayer. playbackRate = self . imageConfiguration. playbackRate
224+ // Setup new player
211225 self . imagePlayer. setupPlayer ( animatedImage: animatedImage)
212226 self . imagePlayer. startPlaying ( )
213227 }
@@ -220,7 +234,7 @@ public struct WebImage : View {
220234 // Don't use `Group` because it will trigger `.onAppear` and `.onDisappear` when condition view removed, treat placeholder as an entire component
221235 if let placeholder = placeholder {
222236 // If use `.delayPlaceholder`, the placeholder is applied after loading failed, hide during loading :)
223- if imageModel. webOptions . contains ( . delayPlaceholder) && imageManager. error == nil {
237+ if imageModel. options . contains ( . delayPlaceholder) && imageManager. error == nil {
224238 return AnyView ( configure ( image: . empty) )
225239 } else {
226240 return placeholder
@@ -347,7 +361,7 @@ extension WebImage {
347361 /// Associate a indicator when loading image with url
348362 /// - Parameter indicator: The indicator type, see `Indicator`
349363 public func indicator< T> ( _ indicator: Indicator < T > ) -> some View where T : View {
350- return self . modifier ( IndicatorViewModifier ( status: imageManager . indicatorStatus, indicator: indicator) )
364+ return self . modifier ( IndicatorViewModifier ( status: indicatorStatus, indicator: indicator) )
351365 }
352366
353367 /// Associate a indicator when loading image with url, convenient method with block
0 commit comments