Skip to content

Commit c55336b

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 a416abe commit c55336b

File tree

4 files changed

+51
-58
lines changed

4 files changed

+51
-58
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/ImageManager.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,16 @@ class ImageManager : ObservableObject {
2222

2323
var url: URL?
2424
var options: SDWebImageOptions
25-
var context: [SDWebImageContextOption : Any]?
25+
var context: [SDWebImageContextOption : Any]
2626
var successBlock: ((PlatformImage, SDImageCacheType) -> Void)?
2727
var failureBlock: ((Error) -> Void)?
2828
var progressBlock: ((Int, Int) -> Void)?
2929

30-
init(url: URL?, options: SDWebImageOptions = [], context: [SDWebImageContextOption : Any]? = nil) {
30+
init(url: URL?, options: SDWebImageOptions = [], context: [SDWebImageContextOption : Any] = [:]) {
3131
self.url = url
3232
self.options = options
3333
self.context = context
34-
if let manager = context?[.customManager] as? SDWebImageManager {
34+
if let manager = context[.customManager] as? SDWebImageManager {
3535
self.manager = manager
3636
} else {
3737
self.manager = .shared

SDWebImageSwiftUI/Classes/WebImage.swift

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

2121
@ObservedObject var imageManager: ImageManager
2222

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

@@ -30,6 +32,23 @@ public struct WebImage : View {
3032
/// - Parameter options: The options to use when downloading the image. See `SDWebImageOptions` for the possible values.
3133
/// - 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.
3234
public init(url: URL?, options: SDWebImageOptions = [], context: [SDWebImageContextOption : Any]? = nil) {
35+
self.init(url: url, options: options, context: context, isAnimating: .constant(false))
36+
}
37+
38+
/// Create a web image with url, placeholder, custom options and context. Optional can support animated image using Binding.
39+
/// - Parameter url: The image url
40+
/// - Parameter options: The options to use when downloading the image. See `SDWebImageOptions` for the possible values.
41+
/// - 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.
42+
/// - 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.
43+
public init(url: URL?, options: SDWebImageOptions = [], context: [SDWebImageContextOption : Any]? = nil, isAnimating: Binding<Bool>) {
44+
self._isAnimating = isAnimating
45+
var context = context ?? [:]
46+
// provide animated image class if the initialized `isAnimating` is true, user can still custom the image class if they want
47+
if isAnimating.wrappedValue {
48+
if context[.animatedImageClass] == nil {
49+
context[.animatedImageClass] = SDAnimatedImage.self
50+
}
51+
}
3352
self.imageManager = ImageManager(url: url, options: options, context: context)
3453
// load remote image here, SwiftUI sometimes will create a new View struct without calling `onAppear` (like enter EditMode) :)
3554
// this can ensure we load the image, SDWebImage take care of the duplicated query
@@ -39,7 +58,7 @@ public struct WebImage : View {
3958
public var body: some View {
4059
Group {
4160
if imageManager.image != nil {
42-
if animated {
61+
if isAnimating {
4362
if currentFrame != nil {
4463
configurations.reduce(Image(platformImage: currentFrame!)) { (previous, configuration) in
4564
configuration(previous)
@@ -59,8 +78,14 @@ public struct WebImage : View {
5978
}
6079
}
6180
} else {
62-
configurations.reduce(Image(platformImage: imageManager.image!)) { (previous, configuration) in
63-
configuration(previous)
81+
if currentFrame != nil {
82+
configurations.reduce(Image(platformImage: currentFrame!)) { (previous, configuration) in
83+
configuration(previous)
84+
}
85+
} else {
86+
configurations.reduce(Image(platformImage: imageManager.image!)) { (previous, configuration) in
87+
configuration(previous)
88+
}
6489
}
6590
}
6691
} else {
@@ -88,6 +113,22 @@ public struct WebImage : View {
88113
}
89114
}
90115
}
116+
117+
/// Animated Image Support
118+
func setupPlayer(image: PlatformImage?) {
119+
if imagePlayer != nil {
120+
return
121+
}
122+
if let animatedImage = image as? SDAnimatedImageProvider {
123+
if let imagePlayer = SDAnimatedImagePlayer(provider: animatedImage) {
124+
imagePlayer.animationFrameHandler = { (_, frame) in
125+
self.currentFrame = frame
126+
}
127+
self.imagePlayer = imagePlayer
128+
imagePlayer.startPlaying()
129+
}
130+
}
131+
}
91132
}
92133

93134
// Layout
@@ -218,52 +259,6 @@ extension WebImage {
218259
}
219260
}
220261

221-
// Animated Image support (Beta)
222-
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
223-
extension WebImage {
224-
225-
/// Make the image to support animated images. The animation will start when view appears, and pause when disappears.
226-
/// - 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)
227-
/// - Warning: This API need polishing. In the future we may choose to create a new View type instead.
228-
///
229-
/// - Parameter animated: Whether or not to enable animationn.
230-
public func animated(_ animated: Bool = true) -> WebImage {
231-
var result = self
232-
result.animated = animated
233-
if animated {
234-
// Update Image Manager
235-
result.imageManager.cancel()
236-
var context = result.imageManager.context ?? [:]
237-
context[.animatedImageClass] = SDAnimatedImage.self
238-
result.imageManager.context = context
239-
result.imageManager.load()
240-
} else {
241-
// Update Image Manager
242-
result.imageManager.cancel()
243-
var context = result.imageManager.context ?? [:]
244-
context[.animatedImageClass] = nil
245-
result.imageManager.context = context
246-
result.imageManager.load()
247-
}
248-
return result
249-
}
250-
251-
func setupPlayer(image: PlatformImage?) {
252-
if imagePlayer != nil {
253-
return
254-
}
255-
if let animatedImage = image as? SDAnimatedImageProvider {
256-
if let imagePlayer = SDAnimatedImagePlayer(provider: animatedImage) {
257-
imagePlayer.animationFrameHandler = { (_, frame) in
258-
self.currentFrame = frame
259-
}
260-
self.imagePlayer = imagePlayer
261-
imagePlayer.startPlaying()
262-
}
263-
}
264-
}
265-
}
266-
267262
#if DEBUG
268263
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
269264
struct WebImage_Previews : PreviewProvider {

0 commit comments

Comments
 (0)