Skip to content

Commit ba9db28

Browse files
committed
Fix the case which sometimes the player does not stop when WebImage it out of screen
This consume CPU because CADisplayLink is still running in the background
1 parent bf3d86b commit ba9db28

File tree

2 files changed

+37
-20
lines changed

2 files changed

+37
-20
lines changed

SDWebImageSwiftUI/Classes/ImagePlayer.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ public final class ImagePlayer : ObservableObject {
3333

3434
deinit {
3535
player?.stopPlaying()
36-
currentFrame = nil
3736
}
3837

3938
/// Current playing frame image
@@ -57,7 +56,7 @@ public final class ImagePlayer : ObservableObject {
5756
if let player = player {
5857
return player.isPlaying && waitingPlaying
5958
}
60-
return false
59+
return true
6160
}
6261

6362
/// Current playing status

SDWebImageSwiftUI/Classes/WebImage.swift

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ public struct WebImage : View {
118118
// Load Logic
119119
setupPlaceholder()
120120
.onPlatformAppear(appear: {
121-
setupManager()
121+
self.setupManager()
122122
if (self.imageManager.error == nil) {
123123
// Load remote image when first appear
124124
self.imageManager.load(url: imageModel.url, options: imageModel.options, context: imageModel.context)
@@ -136,6 +136,8 @@ public struct WebImage : View {
136136
}
137137
})
138138
}
139+
}.onDisappear {
140+
self.disappearAction()
139141
}
140142
}
141143

@@ -205,36 +207,52 @@ public struct WebImage : View {
205207
}
206208
}
207209

210+
/// Animated Image Disappear should stop display link
211+
func disappearAction() {
212+
// Only stop the player which is not intermediate status
213+
if !imagePlayer.isWaiting {
214+
if self.imageConfiguration.pausable {
215+
self.imagePlayer.pausePlaying()
216+
} else {
217+
self.imagePlayer.stopPlaying()
218+
}
219+
if self.imageConfiguration.purgeable {
220+
self.imagePlayer.clearFrameBuffer()
221+
}
222+
}
223+
}
224+
208225
/// Animated Image Support
209226
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-
}
227+
let shouldResetPlayer: Bool
228+
// Image compare should use ===/!==, which is faster than isEqual:
229+
if let animatedImage = imagePlayer.currentAnimatedImage, animatedImage !== imageManager.image! {
230+
shouldResetPlayer = true
231+
} else {
232+
shouldResetPlayer = false
222233
}
223-
if let currentFrame = imagePlayer.currentFrame, imagePlayer.currentAnimatedImage == imageManager.image! {
224-
return configure(image: currentFrame).onPlatformAppear(appear: {
234+
if let currentFrame = imagePlayer.currentFrame, !shouldResetPlayer {
235+
// Bind frame index to ID to ensure onDisappear called with sync
236+
return configure(image: currentFrame)
237+
.id("\(imageModel.url!):\(imagePlayer.currentFrameIndex)")
238+
.onPlatformAppear(appear: {
225239
self.imagePlayer.startPlaying()
226240
}, disappear: {
227241
disappearAction()
228242
})
229243
} else {
230-
return configure(image: imageManager.image!).onPlatformAppear(appear: {
231-
self.imagePlayer.stopPlaying()
232-
if let animatedImage = imageManager.image as? PlatformImage & SDAnimatedImageProvider {
244+
return configure(image: imageManager.image!)
245+
.id("\(imageModel.url!):\(imagePlayer.currentFrameIndex)")
246+
.onPlatformAppear(appear: {
247+
if shouldResetPlayer {
233248
// Clear previous status
249+
self.imagePlayer.stopPlaying()
234250
self.imagePlayer.player = nil;
235251
self.imagePlayer.currentFrame = nil;
236252
self.imagePlayer.currentFrameIndex = 0;
237253
self.imagePlayer.currentLoopCount = 0;
254+
}
255+
if let animatedImage = imageManager.image as? PlatformImage & SDAnimatedImageProvider {
238256
self.imagePlayer.customLoopCount = self.imageConfiguration.customLoopCount
239257
self.imagePlayer.maxBufferSize = self.imageConfiguration.maxBufferSize
240258
self.imagePlayer.runLoopMode = self.imageConfiguration.runLoopMode

0 commit comments

Comments
 (0)