diff --git a/Example/SDWebImageSwiftUIDemo/ContentView.swift b/Example/SDWebImageSwiftUIDemo/ContentView.swift index 171b995a..fe46639a 100644 --- a/Example/SDWebImageSwiftUIDemo/ContentView.swift +++ b/Example/SDWebImageSwiftUIDemo/ContentView.swift @@ -32,7 +32,7 @@ struct ContentView: View { "https://www.sample-videos.com/img/Sample-png-image-1mb.png", "https://nr-platform.s3.amazonaws.com/uploads/platform/published_extension/branding_icon/275/AmazonS3.png", "http://via.placeholder.com/200x200.jpg"] - @State var animated: Bool = true // You can change between WebImage/AnimatedImage + @State var animated: Bool = false // You can change between WebImage/AnimatedImage var body: some View { #if os(iOS) || os(tvOS) diff --git a/SDWebImageSwiftUI/Classes/ImageManager.swift b/SDWebImageSwiftUI/Classes/ImageManager.swift index 9e632cf2..f6ca6969 100644 --- a/SDWebImageSwiftUI/Classes/ImageManager.swift +++ b/SDWebImageSwiftUI/Classes/ImageManager.swift @@ -10,13 +10,14 @@ import SwiftUI import SDWebImage class ImageManager : ObservableObject { - @Published var image: PlatformImage? - @Published var isLoading: Bool = false - @Published var isIncremental: Bool = false - @Published var progress: CGFloat = 0 + @Published var image: PlatformImage? // loaded image, note when progressive loading, this will published multiple times with different partial image + @Published var isLoading: Bool = false // whether network is loading or cache is querying + @Published var progress: CGFloat = 0 // network progress var manager = SDWebImageManager.shared weak var currentOperation: SDWebImageOperation? = nil + var isFinished: Bool = false // true means request end, load() do nothing + var isIncremental: Bool = false // true means during incremental loading var url: URL? var options: SDWebImageOptions @@ -35,7 +36,6 @@ class ImageManager : ObservableObject { if currentOperation != nil { return } - self.image = nil self.isLoading = true currentOperation = manager.loadImage(with: url, options: options, context: context, progress: { [weak self] (receivedSize, expectedSize, _) in guard let self = self else { @@ -55,6 +55,13 @@ class ImageManager : ObservableObject { guard let self = self else { return } + if let error = error as? SDWebImageError, error.code == .cancelled { + // Ignore user cancelled + // There are race condition when quick scroll + // Indicator modifier disapper and trigger `WebImage.body` + // So previous View struct call `onDisappear` and cancel the currentOperation + return + } if let image = image { self.image = image } @@ -63,6 +70,7 @@ class ImageManager : ObservableObject { self.isLoading = false self.progress = 1 if let image = image { + self.isFinished = true self.successBlock?(image, cacheType) } else { self.failureBlock?(error ?? NSError()) diff --git a/SDWebImageSwiftUI/Classes/Indicator/Indicator.swift b/SDWebImageSwiftUI/Classes/Indicator/Indicator.swift index 6898dbe4..e146e0bd 100644 --- a/SDWebImageSwiftUI/Classes/Indicator/Indicator.swift +++ b/SDWebImageSwiftUI/Classes/Indicator/Indicator.swift @@ -32,7 +32,7 @@ struct IndicatorViewModifier : ViewModifier where T : View { var indicator: Indicator func body(content: Content) -> some View { - if !imageManager.isLoading { + if imageManager.isFinished { // Disable Indiactor return AnyView(content) } else { diff --git a/SDWebImageSwiftUI/Classes/WebImage.swift b/SDWebImageSwiftUI/Classes/WebImage.swift index 708104d9..b59fb6c8 100644 --- a/SDWebImageSwiftUI/Classes/WebImage.swift +++ b/SDWebImageSwiftUI/Classes/WebImage.swift @@ -52,7 +52,7 @@ public struct WebImage : View { } let view = image .onAppear { - if self.imageManager.image == nil { + if !self.imageManager.isFinished { self.imageManager.load() } }