Skip to content

Commit 058915b

Browse files
committed
Add the scaleToFit/Fill method to AnimatedImageView, refactory the implementation to use binding
1 parent 875c813 commit 058915b

File tree

2 files changed

+71
-28
lines changed

2 files changed

+71
-28
lines changed

Example/SDWebImageSwiftUIDemo/ContentView.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ struct ContentView: View {
1616
VStack {
1717
WebImage(url: URL(string: "https://nokiatech.github.io/heif/content/images/ski_jump_1440x960.heic"))
1818
.scaledToFit()
19-
.frame(width: 300, height: 300, alignment: .center)
20-
AnimatedImage(url: URL(string: "https://raw.githubusercontent.com/liyong03/YLGIFImage/master/YLGIFImageDemo/YLGIFImageDemo/joy.gif"))
21-
// .scaledToFit() // Apple's Bug ? Custom UIView does not passthrough the `contentMode` from Swift UI layout system into UIKit layout system
22-
.frame(width: 400, height: 300, alignment: .center)
19+
.frame(width: CGFloat(300), height: CGFloat(300), alignment: .center)
20+
AnimatedImage(url: URL(string: "https://raw.githubusercontent.com/liyong03/YLGIFImage/master/YLGIFImageDemo/YLGIFImageDemo/joy.gif"), options: [.progressiveLoad])
21+
.scaledToFill()
22+
.frame(width: CGFloat(400), height: CGFloat(300), alignment: .center)
2323
}
2424
}
2525
}

SDWebImageSwiftUI/Classes/AnimatedImage.swift

Lines changed: 67 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,24 @@ import SDWebImage
1111

1212
#if !os(watchOS)
1313

14-
public struct AnimatedImage: ViewRepresentable {
15-
var url: URL?
16-
var name: String?
17-
var bundle: Bundle?
18-
var data: Data?
19-
var scale: CGFloat = 0
14+
// Data Binding Object
15+
final class AnimatedImageModel : ObservableObject {
16+
@Published var image: SDAnimatedImage?
17+
@Published var url: URL?
18+
}
19+
20+
// Layout Binding Object
21+
final class AnimatedImageLayout : ObservableObject {
22+
@Published var contentMode: ContentMode = .fill
23+
}
24+
25+
// View
26+
public struct AnimatedImage : ViewRepresentable {
27+
@ObservedObject var imageModel = AnimatedImageModel()
28+
@ObservedObject var imageLayout = AnimatedImageLayout()
29+
30+
var webOptions: SDWebImageOptions = []
31+
var webContext: [SDWebImageContextOption : Any]? = nil
2032

2133
#if os(macOS)
2234
public typealias NSViewType = SDAnimatedImageView
@@ -47,36 +59,67 @@ public struct AnimatedImage: ViewRepresentable {
4759
}
4860

4961
func updateView(_ view: SDAnimatedImageView, context: ViewRepresentableContext<AnimatedImage>) {
50-
if let url = url {
51-
view.sd_setImage(with: url)
52-
return
62+
view.image = imageModel.image
63+
if let url = imageModel.url {
64+
view.sd_setImage(with: url, placeholderImage: view.image, options: webOptions, context: webContext)
5365
}
54-
if let name = name {
66+
67+
switch imageLayout.contentMode {
68+
case .fit:
5569
#if os(macOS)
56-
view.image = SDAnimatedImage(named: name, in: bundle)
70+
view.imageScaling = .scaleProportionallyUpOrDown
5771
#else
58-
view.image = SDAnimatedImage(named: name, in: bundle, compatibleWith: nil)
72+
view.contentMode = .scaleAspectFit
73+
#endif
74+
case .fill:
75+
#if os(macOS)
76+
view.imageScaling = .scaleAxesIndependently
77+
#else
78+
view.contentMode = .scaleToFill
5979
#endif
60-
return
61-
}
62-
if let data = data {
63-
view.image = SDAnimatedImage(data: data, scale: scale)
64-
return
6580
}
6681
}
6782

68-
public init(url: URL?, placeholder: Image? = nil, options: SDWebImageOptions = [], context: [SDWebImageContextOption : Any]? = nil) {
69-
self.url = url
83+
public func image(_ image: SDAnimatedImage?) -> Self {
84+
imageModel.image = image
85+
return self
7086
}
7187

72-
public init(name: String, bundle: Bundle? = nil) {
73-
self.name = name
74-
self.bundle = bundle
88+
public func imageUrl(_ url: URL?) -> Self {
89+
imageModel.url = url
90+
return self
7591
}
7692

93+
public func scaledToFit() -> Self {
94+
imageLayout.contentMode = .fit
95+
return self
96+
}
97+
98+
public func scaledToFill() -> Self {
99+
imageLayout.contentMode = .fill
100+
return self
101+
}
102+
}
103+
104+
extension AnimatedImage {
105+
public init(url: URL?, placeholder: SDAnimatedImage? = nil, options: SDWebImageOptions = [], context: [SDWebImageContextOption : Any]? = nil) {
106+
self.webOptions = options
107+
self.webContext = context
108+
self.imageModel.url = url
109+
}
110+
111+
public init(name: String, bundle: Bundle? = nil) {
112+
#if os(macOS)
113+
let image = SDAnimatedImage(named: name, in: bundle)
114+
#else
115+
let image = SDAnimatedImage(named: name, in: bundle, compatibleWith: nil)
116+
#endif
117+
self.imageModel.image = image
118+
}
119+
77120
public init(data: Data, scale: CGFloat = 0) {
78-
self.data = data
79-
self.scale = scale
121+
let image = SDAnimatedImage(data: data, scale: scale)
122+
self.imageModel.image = image
80123
}
81124
}
82125

0 commit comments

Comments
 (0)