From cd85148fc52f38f62e7f9216b7d7bab6c7b4b1b2 Mon Sep 17 00:00:00 2001 From: DreamPiggy Date: Fri, 23 Sep 2022 20:08:40 +0800 Subject: [PATCH] Using the ZStack as a container to distinguish the container disappear vs frame disapppear --- SDWebImageSwiftUI/Classes/ImagePlayer.swift | 16 +++++-- SDWebImageSwiftUI/Classes/WebImage.swift | 53 +++++++++++---------- 2 files changed, 41 insertions(+), 28 deletions(-) diff --git a/SDWebImageSwiftUI/Classes/ImagePlayer.swift b/SDWebImageSwiftUI/Classes/ImagePlayer.swift index 9ab5527..4fdc405 100644 --- a/SDWebImageSwiftUI/Classes/ImagePlayer.swift +++ b/SDWebImageSwiftUI/Classes/ImagePlayer.swift @@ -105,11 +105,21 @@ public final class ImagePlayer : ObservableObject { currentAnimatedImage = animatedImage if let imagePlayer = SDAnimatedImagePlayer(provider: animatedImage) { imagePlayer.animationFrameHandler = { [weak self] (index, frame) in - self?.currentFrameIndex = index - self?.currentFrame = frame + guard let self = self else { + return + } + if (self.isPlaying) { + self.currentFrameIndex = index + self.currentFrame = frame + } } imagePlayer.animationLoopHandler = { [weak self] (loopCount) in - self?.currentLoopCount = loopCount + guard let self = self else { + return + } + if (self.isPlaying) { + self.currentLoopCount = loopCount + } } // Setup configuration if let maxBufferSize = maxBufferSize { diff --git a/SDWebImageSwiftUI/Classes/WebImage.swift b/SDWebImageSwiftUI/Classes/WebImage.swift index 32c3a96..2290182 100644 --- a/SDWebImageSwiftUI/Classes/WebImage.swift +++ b/SDWebImageSwiftUI/Classes/WebImage.swift @@ -102,8 +102,17 @@ public struct WebImage : View { } public var body: some View { - return Group { - // Render Logic + // Container + return ZStack { + // This empty Image is used to receive container's level appear/disappear to start/stop player, reduce CPU usage + Image(platformImage: .empty) + .onAppear { + self.appearAction() + } + .onDisappear { + self.disappearAction() + } + // Render Logic for actual animated image frame or static image if imageManager.image != nil && imageModel.url == imageManager.currentURL { if isAnimating && !imageManager.isIncremental { setupPlayer() @@ -136,8 +145,6 @@ public struct WebImage : View { } }) } - }.onDisappear { - self.disappearAction() } } @@ -207,18 +214,20 @@ public struct WebImage : View { } } - /// Animated Image Disappear should stop display link + /// Container level to resume animation when appear + func appearAction() { + self.imagePlayer.startPlaying() + } + + /// Container level to stop animation when disappear func disappearAction() { - // Only stop the player which is not intermediate status - if !imagePlayer.isWaiting { - if self.imageConfiguration.pausable { - self.imagePlayer.pausePlaying() - } else { - self.imagePlayer.stopPlaying() - } - if self.imageConfiguration.purgeable { - self.imagePlayer.clearFrameBuffer() - } + if self.imageConfiguration.pausable { + self.imagePlayer.pausePlaying() + } else { + self.imagePlayer.stopPlaying() + } + if self.imageConfiguration.purgeable { + self.imagePlayer.clearFrameBuffer() } } @@ -235,19 +244,15 @@ public struct WebImage : View { // Bind frame index to ID to ensure onDisappear called with sync return configure(image: currentFrame) .id("\(imageModel.url!):\(imagePlayer.currentFrameIndex)") - .onPlatformAppear(appear: { - self.imagePlayer.startPlaying() - }, disappear: { - disappearAction() - }) + .onAppear {} } else { return configure(image: imageManager.image!) .id("\(imageModel.url!):\(imagePlayer.currentFrameIndex)") - .onPlatformAppear(appear: { + .onAppear { if shouldResetPlayer { // Clear previous status self.imagePlayer.stopPlaying() - self.imagePlayer.player = nil; + self.imagePlayer.player = nil self.imagePlayer.currentFrame = nil; self.imagePlayer.currentFrameIndex = 0; self.imagePlayer.currentLoopCount = 0; @@ -262,9 +267,7 @@ public struct WebImage : View { self.imagePlayer.setupPlayer(animatedImage: animatedImage) self.imagePlayer.startPlaying() } - }, disappear: { - disappearAction() - }) + } } }