@@ -43,6 +43,11 @@ final class AnimatedLoadingModel : ObservableObject, IndicatorReportable {
43
43
@Published var image : PlatformImage ? // loaded image, note when progressive loading, this will published multiple times with different partial image
44
44
@Published var isLoading : Bool = false // whether network is loading or cache is querying, should only be used for indicator binding
45
45
@Published var progress : Double = 0 // network progress, should only be used for indicator binding
46
+
47
+ /// Used for loading status recording to avoid recursive `updateView`. There are 3 types of loading (Name/Data/URL)
48
+ @Published var imageName : String ?
49
+ @Published var imageData : Data ?
50
+ @Published var imageURL : URL ?
46
51
}
47
52
48
53
/// Completion Handler Binding Object, supports dynamic @State changes
@@ -228,15 +233,19 @@ public struct AnimatedImage : PlatformViewRepresentable {
228
233
}
229
234
self . imageHandler. progressBlock ? ( receivedSize, expectedSize)
230
235
} ) { ( image, data, error, cacheType, finished, _) in
231
- // This is a hack because of Xcode 11.3 bug, the @Published does not trigger another `updateUIView` call
232
- // Here I have to use UIKit/AppKit API to triger the same effect (the window change implicitly cause re-render)
233
- if let hostingView = AnimatedImage . findHostingView ( from: view) {
234
- if let _ = hostingView. window {
235
- #if os(macOS)
236
- hostingView. viewDidMoveToWindow ( )
237
- #else
238
- hostingView. didMoveToWindow ( )
239
- #endif
236
+ if #available( iOS 14 . 0 , macOS 11 . 0 , watchOS 7 . 0 , tvOS 14 . 0 , * ) {
237
+ // Do nothing
238
+ } else {
239
+ // This is a hack because of Xcode 11.3 bug, the @Published does not trigger another `updateUIView` call
240
+ // Here I have to use UIKit/AppKit API to triger the same effect (the window change implicitly cause re-render)
241
+ if let hostingView = AnimatedImage . findHostingView ( from: view) {
242
+ if let _ = hostingView. window {
243
+ #if os(macOS)
244
+ hostingView. viewDidMoveToWindow ( )
245
+ #else
246
+ hostingView. didMoveToWindow ( )
247
+ #endif
248
+ }
240
249
}
241
250
}
242
251
self . imageLoading. image = image
@@ -263,19 +272,20 @@ public struct AnimatedImage : PlatformViewRepresentable {
263
272
func updateView( _ view: AnimatedImageViewWrapper , context: Context ) {
264
273
// Refresh image, imageModel is the Source of Truth, switch the type
265
274
// Although we have Source of Truth, we can check the previous value, to avoid re-generate SDAnimatedImage, which is performance-cost.
266
- if let name = imageModel. name, name != view . wrapped . sd_imageName {
275
+ if let name = imageModel. name, name != imageLoading . imageName {
267
276
#if os(macOS)
268
277
let image = SDAnimatedImage ( named: name, in: imageModel. bundle)
269
278
#else
270
279
let image = SDAnimatedImage ( named: name, in: imageModel. bundle, compatibleWith: nil )
271
280
#endif
272
- view . wrapped . sd_imageName = name
281
+ imageLoading . imageName = name
273
282
view. wrapped. image = image
274
- } else if let data = imageModel. data, data != view . wrapped . sd_imageData {
283
+ } else if let data = imageModel. data, data != imageLoading . imageData {
275
284
let image = SDAnimatedImage ( data: data, scale: imageModel. scale)
276
- view . wrapped . sd_imageData = data
285
+ imageLoading . imageData = data
277
286
view. wrapped. image = image
278
- } else if let url = imageModel. url, url != view. wrapped. sd_imageURL {
287
+ } else if let url = imageModel. url, url != imageLoading. imageURL {
288
+ imageLoading. imageURL = url
279
289
view. wrapped. sd_imageIndicator = imageConfiguration. indicator
280
290
view. wrapped. sd_imageTransition = imageConfiguration. transition
281
291
if let placeholderView = imageConfiguration. placeholderView {
0 commit comments