Skip to content

Commit 8d74623

Browse files
committed
Using the isAnimating arg, instead of protocol extention method to control the WebImage's animation supports. This allows the binding control for animation as well
1 parent 7e92d42 commit 8d74623

File tree

3 files changed

+48
-55
lines changed

3 files changed

+48
-55
lines changed

Example/SDWebImageSwiftUIDemo/ContentView.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,8 @@ struct ContentView: View {
105105
.scaledToFit()
106106
.frame(width: CGFloat(100), height: CGFloat(100), alignment: .center)
107107
#else
108-
WebImage(url: URL(string:url))
108+
WebImage(url: URL(string:url), isAnimating: self.$animated)
109109
.resizable()
110-
.animated()
111110
.indicator { _, _ in
112111
ActivityBar()
113112
.foregroundColor(Color.white)

Example/SDWebImageSwiftUIDemo/DetailView.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,8 @@ struct DetailView: View {
9595
.resizable()
9696
.scaledToFit()
9797
#else
98-
WebImage(url: URL(string:url), options: [.progressiveLoad])
98+
WebImage(url: URL(string:url), options: [.progressiveLoad], isAnimating: $isAnimating)
9999
.resizable()
100-
.animated(isAnimating)
101100
.indicator { isAnimating, progress in
102101
ProgressBar(value: progress)
103102
.foregroundColor(.blue)

SDWebImageSwiftUI/Classes/WebImage.swift

Lines changed: 46 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ public struct WebImage : View {
2121

2222
@ObservedObject var imageManager: ImageManager
2323

24-
// Animated Image support (Beta)
25-
var animated: Bool = false
24+
/// A Binding to control the animation. You can bind external logic to control the animation status.
25+
/// True to start animation, false to stop animation.
26+
@Binding public var isAnimating: Bool
27+
2628
@State var currentFrame: PlatformImage? = nil
2729
@State var imagePlayer: SDAnimatedImagePlayer? = nil
2830

@@ -31,6 +33,23 @@ public struct WebImage : View {
3133
/// - Parameter options: The options to use when downloading the image. See `SDWebImageOptions` for the possible values.
3234
/// - Parameter context: A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.
3335
public init(url: URL?, options: SDWebImageOptions = [], context: [SDWebImageContextOption : Any]? = nil) {
36+
self.init(url: url, options: options, context: context, isAnimating: .constant(false))
37+
}
38+
39+
/// Create a web image with url, placeholder, custom options and context. Optional can support animated image using Binding.
40+
/// - Parameter url: The image url
41+
/// - Parameter options: The options to use when downloading the image. See `SDWebImageOptions` for the possible values.
42+
/// - Parameter context: A context contains different options to perform specify changes or processes, see `SDWebImageContextOption`. This hold the extra objects which `options` enum can not hold.
43+
/// - Parameter isAnimating: The binding for animation control. The binding value should be `true` when initialized to setup the correct animated image class. If not, you must provide the `.animatedImageClass` explicitly. When the animation started, this binding can been used to start / stop the animation.
44+
public init(url: URL?, options: SDWebImageOptions = [], context: [SDWebImageContextOption : Any]? = nil, isAnimating: Binding<Bool>) {
45+
self._isAnimating = isAnimating
46+
var context = context ?? [:]
47+
// provide animated image class if the initialized `isAnimating` is true, user can still custom the image class if they want
48+
if isAnimating.wrappedValue {
49+
if context[.animatedImageClass] == nil {
50+
context[.animatedImageClass] = SDAnimatedImage.self
51+
}
52+
}
3453
self.imageManager = ImageManager(url: url, options: options, context: context)
3554
// load remote image here, SwiftUI sometimes will create a new View struct without calling `onAppear` (like enter EditMode) :)
3655
// this can ensure we load the image, SDWebImage take care of the duplicated query
@@ -40,7 +59,7 @@ public struct WebImage : View {
4059
public var body: some View {
4160
Group {
4261
if imageManager.image != nil {
43-
if animated {
62+
if isAnimating {
4463
if currentFrame != nil {
4564
configurations.reduce(Image(platformImage: currentFrame!)) { (previous, configuration) in
4665
configuration(previous)
@@ -60,8 +79,14 @@ public struct WebImage : View {
6079
}
6180
}
6281
} else {
63-
configurations.reduce(Image(platformImage: imageManager.image!)) { (previous, configuration) in
64-
configuration(previous)
82+
if currentFrame != nil {
83+
configurations.reduce(Image(platformImage: currentFrame!)) { (previous, configuration) in
84+
configuration(previous)
85+
}
86+
} else {
87+
configurations.reduce(Image(platformImage: imageManager.image!)) { (previous, configuration) in
88+
configuration(previous)
89+
}
6590
}
6691
}
6792
} else {
@@ -93,6 +118,22 @@ public struct WebImage : View {
93118
}
94119
}
95120
}
121+
122+
/// Animated Image Support
123+
func setupPlayer(image: PlatformImage?) {
124+
if imagePlayer != nil {
125+
return
126+
}
127+
if let animatedImage = image as? SDAnimatedImageProvider {
128+
if let imagePlayer = SDAnimatedImagePlayer(provider: animatedImage) {
129+
imagePlayer.animationFrameHandler = { (_, frame) in
130+
self.currentFrame = frame
131+
}
132+
self.imagePlayer = imagePlayer
133+
imagePlayer.startPlaying()
134+
}
135+
}
136+
}
96137
}
97138

98139
// Layout
@@ -223,52 +264,6 @@ extension WebImage {
223264
}
224265
}
225266

226-
// Animated Image support (Beta)
227-
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
228-
extension WebImage {
229-
230-
/// Make the image to support animated images. The animation will start when view appears, and pause when disappears.
231-
/// - Note: Currently we do not have advanced control like binding, reset frame index, playback rate, etc. For those use case, it's recommend to use `AnimatedImage` type instead. (support iOS/tvOS/macOS)
232-
/// - Warning: This API need polishing. In the future we may choose to create a new View type instead.
233-
///
234-
/// - Parameter animated: Whether or not to enable animationn.
235-
public func animated(_ animated: Bool = true) -> WebImage {
236-
var result = self
237-
result.animated = animated
238-
if animated {
239-
// Update Image Manager
240-
result.imageManager.cancel()
241-
var context = result.imageManager.context ?? [:]
242-
context[.animatedImageClass] = SDAnimatedImage.self
243-
result.imageManager.context = context
244-
result.imageManager.load()
245-
} else {
246-
// Update Image Manager
247-
result.imageManager.cancel()
248-
var context = result.imageManager.context ?? [:]
249-
context[.animatedImageClass] = nil
250-
result.imageManager.context = context
251-
result.imageManager.load()
252-
}
253-
return result
254-
}
255-
256-
func setupPlayer(image: PlatformImage?) {
257-
if imagePlayer != nil {
258-
return
259-
}
260-
if let animatedImage = image as? SDAnimatedImageProvider {
261-
if let imagePlayer = SDAnimatedImagePlayer(provider: animatedImage) {
262-
imagePlayer.animationFrameHandler = { (_, frame) in
263-
self.currentFrame = frame
264-
}
265-
self.imagePlayer = imagePlayer
266-
imagePlayer.startPlaying()
267-
}
268-
}
269-
}
270-
}
271-
272267
#if DEBUG
273268
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
274269
struct WebImage_Previews : PreviewProvider {

0 commit comments

Comments
 (0)