Skip to content

Commit 1d7efec

Browse files
committed
Fix the empty placeholder may cause onAppear does not called
Move the reset logic into helper function setupManager
1 parent d281bde commit 1d7efec

File tree

3 files changed

+48
-22
lines changed

3 files changed

+48
-22
lines changed

Example/SDWebImageSwiftUIDemo/ContentView.swift

+4
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ struct ContentView2: View {
6565
imageIndex += 1
6666
}
6767
}
68+
Button("Reload") {
69+
SDImageCache.shared.clearMemory()
70+
SDImageCache.shared.clearDisk(onCompletion: nil)
71+
}
6872
Toggle("Switch", isOn: $animated)
6973
}
7074
}

SDWebImageSwiftUI/Classes/ImageManager.swift

+1
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ public final class ImageManager : ObservableObject {
101101
currentOperation = nil
102102
}
103103
indicatorStatus.isLoading = false
104+
currentURL = nil
104105
}
105106

106107
}

SDWebImageSwiftUI/Classes/WebImage.swift

+43-22
Original file line numberDiff line numberDiff line change
@@ -103,22 +103,10 @@ public struct WebImage : View {
103103

104104
public var body: some View {
105105
return Group {
106+
// Render Logic
106107
if imageManager.image != nil && imageModel.url == imageManager.currentURL {
107108
if isAnimating && !imageManager.isIncremental {
108109
setupPlayer()
109-
.onDisappear {
110-
// Only stop the player which is not intermediate status
111-
if !imagePlayer.isWaiting {
112-
if self.imageConfiguration.pausable {
113-
self.imagePlayer.pausePlaying()
114-
} else {
115-
self.imagePlayer.stopPlaying()
116-
}
117-
if self.imageConfiguration.purgeable {
118-
self.imagePlayer.clearFrameBuffer()
119-
}
120-
}
121-
}
122110
} else {
123111
if let currentFrame = imagePlayer.currentFrame {
124112
configure(image: currentFrame)
@@ -127,11 +115,10 @@ public struct WebImage : View {
127115
}
128116
}
129117
} else {
118+
// Load Logic
130119
setupPlaceholder()
131120
.onPlatformAppear(appear: {
132-
self.imageManager.successBlock = self.imageHandler.successBlock
133-
self.imageManager.failureBlock = self.imageHandler.failureBlock
134-
self.imageManager.progressBlock = self.imageHandler.progressBlock
121+
setupManager()
135122
if (self.imageManager.error == nil) {
136123
// Load remote image when first appear
137124
self.imageManager.load(url: imageModel.url, options: imageModel.options, context: imageModel.context)
@@ -201,14 +188,46 @@ public struct WebImage : View {
201188
}
202189
}
203190

191+
/// Image Manager status
192+
func setupManager() {
193+
self.imageManager.successBlock = self.imageHandler.successBlock
194+
self.imageManager.failureBlock = self.imageHandler.failureBlock
195+
self.imageManager.progressBlock = self.imageHandler.progressBlock
196+
if imageModel.url != imageManager.currentURL {
197+
imageManager.cancel()
198+
imageManager.image = nil
199+
imageManager.imageData = nil
200+
imageManager.cacheType = .none
201+
imageManager.error = nil
202+
imageManager.isIncremental = false
203+
imageManager.indicatorStatus.isLoading = false
204+
imageManager.indicatorStatus.progress = 0
205+
}
206+
}
207+
204208
/// Animated Image Support
205209
func setupPlayer() -> some View {
210+
let disappearAction = {
211+
// Only stop the player which is not intermediate status
212+
if !imagePlayer.isWaiting {
213+
if self.imageConfiguration.pausable {
214+
self.imagePlayer.pausePlaying()
215+
} else {
216+
self.imagePlayer.stopPlaying()
217+
}
218+
if self.imageConfiguration.purgeable {
219+
self.imagePlayer.clearFrameBuffer()
220+
}
221+
}
222+
}
206223
if let currentFrame = imagePlayer.currentFrame, imagePlayer.currentAnimatedImage == imageManager.image! {
207-
return configure(image: currentFrame).onAppear {
224+
return configure(image: currentFrame).onPlatformAppear(appear: {
208225
self.imagePlayer.startPlaying()
209-
}
226+
}, disappear: {
227+
disappearAction()
228+
})
210229
} else {
211-
return configure(image: imageManager.image!).onAppear {
230+
return configure(image: imageManager.image!).onPlatformAppear(appear: {
212231
self.imagePlayer.stopPlaying()
213232
if let animatedImage = imageManager.image as? PlatformImage & SDAnimatedImageProvider {
214233
// Clear previous status
@@ -225,7 +244,9 @@ public struct WebImage : View {
225244
self.imagePlayer.setupPlayer(animatedImage: animatedImage)
226245
self.imagePlayer.startPlaying()
227246
}
228-
}
247+
}, disappear: {
248+
disappearAction()
249+
})
229250
}
230251
}
231252

@@ -235,12 +256,12 @@ public struct WebImage : View {
235256
if let placeholder = placeholder {
236257
// If use `.delayPlaceholder`, the placeholder is applied after loading failed, hide during loading :)
237258
if imageModel.options.contains(.delayPlaceholder) && imageManager.error == nil {
238-
return AnyView(configure(image: .empty))
259+
return AnyView(configure(image: .empty).id(UUID())) // UUID to avoid SwiftUI engine cache the status and does not call `onAppear`
239260
} else {
240261
return placeholder
241262
}
242263
} else {
243-
return AnyView(configure(image: .empty))
264+
return AnyView(configure(image: .empty).id(UUID())) // UUID to avoid SwiftUI engine cache the status and does not call `onAppear`
244265
}
245266
}
246267
}

0 commit comments

Comments
 (0)