Skip to content

Commit 840b672

Browse files
authored
Merge pull request #13 from SDWebImage/feature_animatedimage_modifier
Feature animatedimage modifier
2 parents 2997c45 + 7d6e2f3 commit 840b672

File tree

3 files changed

+77
-22
lines changed

3 files changed

+77
-22
lines changed

README.md

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,10 @@ let package = Package(
6161

6262
## Usage
6363

64-
+ Using `WebImage` to load network image
64+
### Using `WebImage` to load network image
6565

66-
Supports the placeholder and detail options control for image loading as SDWebImage.
67-
68-
Supports the success/failure/progress changes event for custom handling.
66+
- [x] Supports the placeholder and detail options control for image loading as SDWebImage.
67+
- [x] Supports the success/failure/progress changes event for custom handling.
6968

7069
Note: Unlike `UIImageView` in UIKit, SwiftUI's `Image` does not support animation. This `WebImage` using `Image` for internal implementation and supports static image format only.
7170

@@ -81,20 +80,25 @@ var body: some View {
8180
}
8281
```
8382

84-
+ Using `AnimatedImage` to play animation
83+
### Using `AnimatedImage` to play animation
8584

8685
```swift
8786
var body: some View {
88-
AnimatedImage(url: URL(string: "https://raw.githubusercontent.com/liyong03/YLGIFImage/master/YLGIFImageDemo/YLGIFImageDemo/joy.gif"))
89-
.onFailure(perform: { (error) in
90-
// Error
91-
})
92-
.scaledToFit()
93-
AnimatedImage(data: try! Data(contentsOf: URL(fileURLWithPath: "/tmp/foo.webp")))
94-
.scaledToFill()
87+
Group {
88+
AnimatedImage(url: URL(string: "https://raw.githubusercontent.com/liyong03/YLGIFImage/master/YLGIFImageDemo/YLGIFImageDemo/joy.gif"))
89+
.onFailure(perform: { (error) in
90+
// Error
91+
})
92+
.scaledToFit()
93+
AnimatedImage(data: try! Data(contentsOf: URL(fileURLWithPath: "/tmp/foo.webp")))
94+
.customLoopCount(1)
95+
}
9596
}
9697
```
9798

99+
- [x] Supports network image as well as local data and bundle image
100+
- [x] Supports advanced control like loop count, incremental load, buffer size.
101+
98102
Note: `AnimatedImage` supports both image url or image data for animated image format. Which use the SDWebImage's [Animated ImageView](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#animated-image-50) for internal implementation.
99103

100104
## Demo

SDWebImageSwiftUI/Classes/AnimatedImage.swift

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,18 @@ final class AnimatedImageLayout : ObservableObject {
3131
@Published var antialiased: Bool = false
3232
}
3333

34+
// Configuration Binding Object
35+
final class AnimatedImageConfiguration: ObservableObject {
36+
@Published var incrementalLoad: Bool?
37+
@Published var maxBufferSize: UInt?
38+
@Published var customLoopCount: Int?
39+
}
40+
3441
// View
35-
public struct AnimatedImage : ViewRepresentable {
42+
public struct AnimatedImage : PlatformViewRepresentable {
3643
@ObservedObject var imageModel = AnimatedImageModel()
3744
@ObservedObject var imageLayout = AnimatedImageLayout()
45+
@ObservedObject var imageConfiguration = AnimatedImageConfiguration()
3846

3947
var placeholder: PlatformImage?
4048
var webOptions: SDWebImageOptions = []
@@ -64,11 +72,11 @@ public struct AnimatedImage : ViewRepresentable {
6472
}
6573
#endif
6674

67-
func makeView(context: ViewRepresentableContext<AnimatedImage>) -> AnimatedImageViewWrapper {
75+
func makeView(context: PlatformViewRepresentableContext<AnimatedImage>) -> AnimatedImageViewWrapper {
6876
AnimatedImageViewWrapper()
6977
}
7078

71-
func updateView(_ view: AnimatedImageViewWrapper, context: ViewRepresentableContext<AnimatedImage>) {
79+
func updateView(_ view: AnimatedImageViewWrapper, context: PlatformViewRepresentableContext<AnimatedImage>) {
7280
view.wrapped.image = imageModel.image
7381
if let url = imageModel.url {
7482
view.wrapped.sd_setImage(with: url, placeholderImage: placeholder, options: webOptions, context: webContext, progress: { (receivedSize, expectedSize, _) in
@@ -82,10 +90,11 @@ public struct AnimatedImage : ViewRepresentable {
8290
}
8391
}
8492

93+
configureView(view, context: context)
8594
layoutView(view, context: context)
8695
}
8796

88-
func layoutView(_ view: AnimatedImageViewWrapper, context: ViewRepresentableContext<AnimatedImage>) {
97+
func layoutView(_ view: AnimatedImageViewWrapper, context: PlatformViewRepresentableContext<AnimatedImage>) {
8998
// AspectRatio
9099
if let _ = imageLayout.aspectRatio {
91100
// TODO: Needs layer transform and geometry calculation
@@ -190,6 +199,30 @@ public struct AnimatedImage : ViewRepresentable {
190199
view.setNeedsDisplay()
191200
#endif
192201
}
202+
203+
func configureView(_ view: AnimatedImageViewWrapper, context: PlatformViewRepresentableContext<AnimatedImage>) {
204+
// IncrementalLoad
205+
if let incrementalLoad = imageConfiguration.incrementalLoad {
206+
view.wrapped.shouldIncrementalLoad = incrementalLoad
207+
}
208+
209+
// MaxBufferSize
210+
if let maxBufferSize = imageConfiguration.maxBufferSize {
211+
view.wrapped.maxBufferSize = maxBufferSize
212+
} else {
213+
// automatically
214+
view.wrapped.maxBufferSize = 0
215+
}
216+
217+
// CustomLoopCount
218+
if let customLoopCount = imageConfiguration.customLoopCount {
219+
view.wrapped.shouldCustomLoopCount = true
220+
view.wrapped.animationRepeatCount = customLoopCount
221+
} else {
222+
// disable custom loop count
223+
view.wrapped.shouldCustomLoopCount = false
224+
}
225+
}
193226
}
194227

195228
// Layout
@@ -241,6 +274,24 @@ extension AnimatedImage {
241274
}
242275
}
243276

277+
// AnimatedImage Modifier
278+
extension AnimatedImage {
279+
public func customLoopCount(_ loopCount: Int?) -> AnimatedImage {
280+
imageConfiguration.customLoopCount = loopCount
281+
return self
282+
}
283+
284+
public func maxBufferSize(_ bufferSize: UInt?) -> AnimatedImage {
285+
imageConfiguration.maxBufferSize = bufferSize
286+
return self
287+
}
288+
289+
public func incrementalLoad(_ incrementalLoad: Bool) -> AnimatedImage {
290+
imageConfiguration.incrementalLoad = incrementalLoad
291+
return self
292+
}
293+
}
294+
244295
// Completion Handler
245296
extension AnimatedImage {
246297
public func onFailure(perform action: ((Error) -> Void)? = nil) -> AnimatedImage {

SDWebImageSwiftUI/Classes/SDWebImageSwiftUI.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,14 @@ public typealias PlatformView = WKInterfaceObject
3636
#endif
3737

3838
#if os(macOS)
39-
typealias ViewRepresentable = NSViewRepresentable
40-
typealias ViewRepresentableContext = NSViewRepresentableContext
39+
typealias PlatformViewRepresentable = NSViewRepresentable
40+
typealias PlatformViewRepresentableContext = NSViewRepresentableContext
4141
#endif
4242
#if os(iOS) || os(tvOS)
43-
typealias ViewRepresentable = UIViewRepresentable
44-
typealias ViewRepresentableContext = UIViewRepresentableContext
43+
typealias PlatformViewRepresentable = UIViewRepresentable
44+
typealias PlatformViewRepresentableContext = UIViewRepresentableContext
4545
#endif
4646
#if os(watchOS)
47-
typealias ViewRepresentable = WKInterfaceObjectRepresentable
48-
typealias ViewRepresentableContext = WKInterfaceObjectRepresentableContext
47+
typealias PlatformViewRepresentable = WKInterfaceObjectRepresentable
48+
typealias PlatformViewRepresentableContext = WKInterfaceObjectRepresentableContext
4949
#endif

0 commit comments

Comments
 (0)