Переглянути джерело

Fine-tune for the image rendering trigger

Especially when startLoadingBeforeViewAppear is true
onevcat 3 роки тому
батько
коміт
2eb1cff4b2

+ 25 - 6
Sources/SwiftUI/ImageBinder.swift

@@ -46,9 +46,23 @@ extension KFImage {
 
 
         // Do not use @Published due to https://github.com/onevcat/Kingfisher/issues/1717. Revert to @Published once
         // Do not use @Published due to https://github.com/onevcat/Kingfisher/issues/1717. Revert to @Published once
         // we can drop iOS 12.
         // we can drop iOS 12.
-        var loaded = false                           { willSet { objectWillChange.send() } }
+        private(set) var loaded = false
+
+        private(set) var animating = false
+
         var loadedImage: KFCrossPlatformImage? = nil { willSet { objectWillChange.send() } }
         var loadedImage: KFCrossPlatformImage? = nil { willSet { objectWillChange.send() } }
-        var progress: Progress = .init()             { willSet { objectWillChange.send() } }
+        var progress: Progress = .init()
+
+        func markLoading() {
+            loading = true
+        }
+
+        func markLoaded(sendChangeEvent: Bool) {
+            loaded = true
+            if sendChangeEvent {
+                objectWillChange.send()
+            }
+        }
 
 
         func start<HoldingView: KFImageHoldingView>(context: Context<HoldingView>) {
         func start<HoldingView: KFImageHoldingView>(context: Context<HoldingView>) {
             guard let source = context.source else {
             guard let source = context.source else {
@@ -58,7 +72,7 @@ extension KFImage {
                         self.loadedImage = image
                         self.loadedImage = image
                     }
                     }
                     self.loading = false
                     self.loading = false
-                    self.loaded = true
+                    self.markLoaded(sendChangeEvent: false)
                 }
                 }
                 return
                 return
             }
             }
@@ -87,12 +101,17 @@ extension KFImage {
                         case .success(let value):
                         case .success(let value):
                             CallbackQueue.mainCurrentOrAsync.execute {
                             CallbackQueue.mainCurrentOrAsync.execute {
                                 if let fadeDuration = context.fadeTransitionDuration(cacheType: value.cacheType) {
                                 if let fadeDuration = context.fadeTransitionDuration(cacheType: value.cacheType) {
+                                    self.animating = true
                                     let animation = Animation.linear(duration: fadeDuration)
                                     let animation = Animation.linear(duration: fadeDuration)
-                                    withAnimation(animation) { self.loaded = true }
+                                    withAnimation(animation) {
+                                        // Trigger the view render to apply the animation.
+                                        self.markLoaded(sendChangeEvent: true)
+                                    }
                                 } else {
                                 } else {
-                                    self.loaded = true
+                                    self.markLoaded(sendChangeEvent: false)
                                 }
                                 }
                                 self.loadedImage = value.image
                                 self.loadedImage = value.image
+                                self.animating = false
                             }
                             }
 
 
                             CallbackQueue.mainAsync.execute {
                             CallbackQueue.mainAsync.execute {
@@ -103,7 +122,7 @@ extension KFImage {
                                 if let image = context.options.onFailureImage {
                                 if let image = context.options.onFailureImage {
                                     self.loadedImage = image
                                     self.loadedImage = image
                                 }
                                 }
-                                self.loaded = true
+                                self.markLoaded(sendChangeEvent: true)
                             }
                             }
                             
                             
                             CallbackQueue.mainAsync.execute {
                             CallbackQueue.mainAsync.execute {

+ 2 - 1
Sources/SwiftUI/KFImageRenderer.swift

@@ -37,7 +37,8 @@ struct KFImageRenderer<HoldingView> : View where HoldingView: KFImageHoldingView
     let context: KFImage.Context<HoldingView>
     let context: KFImage.Context<HoldingView>
     
     
     var body: some View {
     var body: some View {
-        if context.startLoadingBeforeViewAppear && !binder.loadingOrSucceeded {
+        if context.startLoadingBeforeViewAppear && !binder.loadingOrSucceeded && !binder.animating {
+            binder.markLoading()
             DispatchQueue.main.async { binder.start(context: context) }
             DispatchQueue.main.async { binder.start(context: context) }
         }
         }