@@ -102,8 +102,17 @@ public struct WebImage : View {
102102 }
103103
104104 public var body : some View {
105- return Group {
106- // Render Logic
105+ // Container
106+ return ZStack {
107+ // This empty Image is used to receive container's level appear/disappear to start/stop player, reduce CPU usage
108+ Image ( platformImage: . empty)
109+ . onAppear {
110+ self . appearAction ( )
111+ }
112+ . onDisappear {
113+ self . disappearAction ( )
114+ }
115+ // Render Logic for actual animated image frame or static image
107116 if imageManager. image != nil && imageModel. url == imageManager. currentURL {
108117 if isAnimating && !imageManager. isIncremental {
109118 setupPlayer ( )
@@ -118,7 +127,7 @@ public struct WebImage : View {
118127 // Load Logic
119128 setupPlaceholder ( )
120129 . onPlatformAppear ( appear: {
121- setupManager ( )
130+ self . setupManager ( )
122131 if ( self . imageManager. error == nil ) {
123132 // Load remote image when first appear
124133 self . imageManager. load ( url: imageModel. url, options: imageModel. options, context: imageModel. context)
@@ -205,36 +214,50 @@ public struct WebImage : View {
205214 }
206215 }
207216
217+ /// Container level to resume animation when appear
218+ func appearAction( ) {
219+ self . imagePlayer. startPlaying ( )
220+ }
221+
222+ /// Container level to stop animation when disappear
223+ func disappearAction( ) {
224+ if self . imageConfiguration. pausable {
225+ self . imagePlayer. pausePlaying ( )
226+ } else {
227+ self . imagePlayer. stopPlaying ( )
228+ }
229+ if self . imageConfiguration. purgeable {
230+ self . imagePlayer. clearFrameBuffer ( )
231+ }
232+ }
233+
208234 /// Animated Image Support
209235 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- }
236+ let shouldResetPlayer : Bool
237+ // Image compare should use ===/!==, which is faster than isEqual:
238+ if let animatedImage = imagePlayer. currentAnimatedImage, animatedImage !== imageManager. image! {
239+ shouldResetPlayer = true
240+ } else {
241+ shouldResetPlayer = false
222242 }
223- if let currentFrame = imagePlayer. currentFrame, imagePlayer. currentAnimatedImage == imageManager. image! {
224- return configure ( image: currentFrame) . onPlatformAppear ( appear: {
225- self . imagePlayer. startPlaying ( )
226- } , disappear: {
227- disappearAction ( )
228- } )
243+ if let currentFrame = imagePlayer. currentFrame, !shouldResetPlayer {
244+ // Bind frame index to ID to ensure onDisappear called with sync
245+ return configure ( image: currentFrame)
246+ . id ( " \( imageModel. url!) : \( imagePlayer. currentFrameIndex) " )
247+ . onAppear { }
229248 } else {
230- return configure ( image: imageManager. image!) . onPlatformAppear ( appear: {
231- self . imagePlayer. stopPlaying ( )
232- if let animatedImage = imageManager. image as? PlatformImage & SDAnimatedImageProvider {
249+ return configure ( image: imageManager. image!)
250+ . id ( " \( imageModel. url!) : \( imagePlayer. currentFrameIndex) " )
251+ . onAppear {
252+ if shouldResetPlayer {
233253 // Clear previous status
234- self . imagePlayer. player = nil ;
254+ self . imagePlayer. stopPlaying ( )
255+ self . imagePlayer. player = nil
235256 self . imagePlayer. currentFrame = nil ;
236257 self . imagePlayer. currentFrameIndex = 0 ;
237258 self . imagePlayer. currentLoopCount = 0 ;
259+ }
260+ if let animatedImage = imageManager. image as? PlatformImage & SDAnimatedImageProvider {
238261 self . imagePlayer. customLoopCount = self . imageConfiguration. customLoopCount
239262 self . imagePlayer. maxBufferSize = self . imageConfiguration. maxBufferSize
240263 self . imagePlayer. runLoopMode = self . imageConfiguration. runLoopMode
@@ -244,9 +267,7 @@ public struct WebImage : View {
244267 self . imagePlayer. setupPlayer ( animatedImage: animatedImage)
245268 self . imagePlayer. startPlaying ( )
246269 }
247- } , disappear: {
248- disappearAction ( )
249- } )
270+ }
250271 }
251272 }
252273
0 commit comments