Skip to content

Commit e478865

Browse files
committed
Fix the issue that AnimatedImage can not refresh their url/name/data after first initializer. Uisng the same design as SwiftUI, which take a Single south of truth to refresh everytime when updateView is called
1 parent 1ad3ef8 commit e478865

File tree

1 file changed

+39
-34
lines changed

1 file changed

+39
-34
lines changed

SDWebImageSwiftUI/Classes/AnimatedImage.swift

Lines changed: 39 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,23 @@ public final class AnimatedImageCoordinator: NSObject {
1919
public var userInfo: [AnyHashable : Any]?
2020
}
2121

22+
/// Data Binding Object, only properties in this object can support changes from user with @State and refresh
23+
final class AnimatedImageModel : ObservableObject {
24+
/// URL image
25+
@Published var url: URL?
26+
@Published var webOptions: SDWebImageOptions = []
27+
@Published var webContext: [SDWebImageContextOption : Any]? = nil
28+
/// Name image
29+
@Published var name: String?
30+
@Published var bundle: Bundle?
31+
/// Data image
32+
@Published var data: Data?
33+
@Published var scale: CGFloat = 1
34+
}
35+
2236
/// A Image View type to load image from url, data or bundle. Supports animated and static image format.
2337
public struct AnimatedImage : PlatformViewRepresentable {
24-
// Options
25-
var url: URL?
26-
var webOptions: SDWebImageOptions = []
27-
var webContext: [SDWebImageContextOption : Any]? = nil
38+
@ObservedObject var imageModel = AnimatedImageModel()
2839

2940
// Completion Handler
3041
var successBlock: ((PlatformImage, SDImageCacheType) -> Void)?
@@ -60,9 +71,6 @@ public struct AnimatedImage : PlatformViewRepresentable {
6071
var viewUpdateBlock: ((PlatformView, Context) -> Void)?
6172
static var viewDestroyBlock: ((PlatformView, Coordinator) -> Void)?
6273

63-
/// Current loaded image, may be `SDAnimatedImage` type
64-
@State public var image: PlatformImage?
65-
6674
/// A Binding to control the animation. You can bind external logic to control the animation status.
6775
/// True to start animation, false to stop animation.
6876
@Binding public var isAnimating: Bool
@@ -84,9 +92,9 @@ public struct AnimatedImage : PlatformViewRepresentable {
8492
/// - Parameter isAnimating: The binding for animation control
8593
public init(url: URL?, options: SDWebImageOptions = [], context: [SDWebImageContextOption : Any]? = nil, isAnimating: Binding<Bool>) {
8694
self._isAnimating = isAnimating
87-
self.webOptions = options
88-
self.webContext = context
89-
self.url = url
95+
self.imageModel.url = url
96+
self.imageModel.webOptions = options
97+
self.imageModel.webContext = context
9098
}
9199

92100
/// Create an animated image with name and bundle.
@@ -104,12 +112,8 @@ public struct AnimatedImage : PlatformViewRepresentable {
104112
/// - Parameter isAnimating: The binding for animation control
105113
public init(name: String, bundle: Bundle? = nil, isAnimating: Binding<Bool>) {
106114
self._isAnimating = isAnimating
107-
#if os(macOS) || os(watchOS)
108-
let image = SDAnimatedImage(named: name, in: bundle)
109-
#else
110-
let image = SDAnimatedImage(named: name, in: bundle, compatibleWith: nil)
111-
#endif
112-
_image = .init(wrappedValue: image)
115+
self.imageModel.name = name
116+
self.imageModel.bundle = bundle
113117
}
114118

115119
/// Create an animated image with data and scale.
@@ -125,8 +129,8 @@ public struct AnimatedImage : PlatformViewRepresentable {
125129
/// - Parameter isAnimating: The binding for animation control
126130
public init(data: Data, scale: CGFloat = 0, isAnimating: Binding<Bool>) {
127131
self._isAnimating = isAnimating
128-
let image = SDAnimatedImage(data: data, scale: scale)
129-
_image = .init(wrappedValue: image)
132+
self.imageModel.data = data
133+
self.imageModel.scale = scale
130134
}
131135

132136
#if os(macOS)
@@ -181,7 +185,7 @@ public struct AnimatedImage : PlatformViewRepresentable {
181185
}
182186
#endif
183187

184-
func loadImage(_ view: AnimatedImageViewWrapper, url: URL) {
188+
func loadImage(_ view: AnimatedImageViewWrapper, context: Context, url: URL, webOptions: SDWebImageOptions = [], webContext: [SDWebImageContextOption : Any]? = nil) {
185189
let operationKey = NSStringFromClass(type(of: view.wrapped))
186190
let currentOperation = view.wrapped.sd_imageLoadOperation(forKey: operationKey)
187191
if currentOperation != nil {
@@ -190,9 +194,7 @@ public struct AnimatedImage : PlatformViewRepresentable {
190194
view.wrapped.sd_setImage(with: url, placeholderImage: placeholder, options: webOptions, context: webContext, progress: { (receivedSize, expectedSize, _) in
191195
self.progressBlock?(receivedSize, expectedSize)
192196
}) { (image, error, cacheType, _) in
193-
DispatchQueue.main.async {
194-
self.image = image
195-
}
197+
self.layoutView(view, context: context)
196198
if let image = image {
197199
self.successBlock?(image, cacheType)
198200
} else {
@@ -210,20 +212,23 @@ public struct AnimatedImage : PlatformViewRepresentable {
210212
}
211213

212214
func updateView(_ view: AnimatedImageViewWrapper, context: Context) {
213-
if let image = self.image {
214-
#if os(watchOS)
215-
view.wrapped.setImage(image)
215+
// Refresh image, imageModel is the South of Truth, switch the type
216+
if let name = imageModel.name {
217+
#if os(macOS) || os(watchOS)
218+
let image = SDAnimatedImage(named: name, in: imageModel.bundle)
216219
#else
220+
let image = SDAnimatedImage(named: name, in: imageModel.bundle, compatibleWith: nil)
221+
#endif
222+
view.wrapped.image = image
223+
} else if let data = imageModel.data {
224+
let image = SDAnimatedImage(data: data, scale: imageModel.scale)
217225
view.wrapped.image = image
226+
} else if let url = imageModel.url {
227+
#if os(macOS) || os(iOS) || os(tvOS)
228+
view.wrapped.sd_imageIndicator = self.indicator
229+
view.wrapped.sd_imageTransition = self.transition
218230
#endif
219-
} else {
220-
if let url = url {
221-
#if os(macOS) || os(iOS) || os(tvOS)
222-
view.wrapped.sd_imageIndicator = self.indicator
223-
view.wrapped.sd_imageTransition = self.transition
224-
#endif
225-
loadImage(view, url: url)
226-
}
231+
loadImage(view, context: context, url: url, webOptions: imageModel.webOptions, webContext: imageModel.webContext)
227232
}
228233

229234
#if os(macOS)
@@ -324,7 +329,7 @@ public struct AnimatedImage : PlatformViewRepresentable {
324329
#endif
325330

326331
// Animated Image does not support resizing mode and rendering mode
327-
if let image = self.image, !image.sd_isAnimated, !image.conforms(to: SDAnimatedImageProtocol.self) {
332+
if let image = view.wrapped.image, !image.sd_isAnimated, !image.conforms(to: SDAnimatedImageProtocol.self) {
328333
var image = image
329334
// ResizingMode
330335
if let resizingMode = self.resizingMode, capInsets != EdgeInsets() {

0 commit comments

Comments
 (0)