@@ -20,6 +20,10 @@ final class AnimatedImageModel : ObservableObject {
2020// Layout Binding Object
2121final class AnimatedImageLayout : ObservableObject {
2222 @Published var contentMode : ContentMode = . fill
23+ @Published var aspectRatio : CGFloat ?
24+ @Published var renderingMode : Image . TemplateRenderingMode ?
25+ @Published var interpolation : Image . Interpolation ?
26+ @Published var antialiased : Bool = false
2327}
2428
2529// View
@@ -31,53 +35,111 @@ public struct AnimatedImage : ViewRepresentable {
3135 var webContext : [ SDWebImageContextOption : Any ] ? = nil
3236
3337 #if os(macOS)
34- public typealias NSViewType = SDAnimatedImageView
38+ public typealias NSViewType = AnimatedImageViewWrapper
3539 #else
36- public typealias UIViewType = SDAnimatedImageView
40+ public typealias UIViewType = AnimatedImageViewWrapper
3741 #endif
3842
3943 #if os(macOS)
40- public func makeNSView( context: NSViewRepresentableContext < AnimatedImage > ) -> SDAnimatedImageView {
44+ public func makeNSView( context: NSViewRepresentableContext < AnimatedImage > ) -> AnimatedImageViewWrapper {
4145 makeView ( context: context)
4246 }
4347
44- public func updateNSView( _ nsView: SDAnimatedImageView , context: NSViewRepresentableContext < AnimatedImage > ) {
48+ public func updateNSView( _ nsView: AnimatedImageViewWrapper , context: NSViewRepresentableContext < AnimatedImage > ) {
4549 updateView ( nsView, context: context)
4650 }
4751 #else
48- public func makeUIView( context: UIViewRepresentableContext < AnimatedImage > ) -> SDAnimatedImageView {
52+ public func makeUIView( context: UIViewRepresentableContext < AnimatedImage > ) -> AnimatedImageViewWrapper {
4953 makeView ( context: context)
5054 }
5155
52- public func updateUIView( _ uiView: SDAnimatedImageView , context: UIViewRepresentableContext < AnimatedImage > ) {
56+ public func updateUIView( _ uiView: AnimatedImageViewWrapper , context: UIViewRepresentableContext < AnimatedImage > ) {
5357 updateView ( uiView, context: context)
5458 }
5559 #endif
5660
57- func makeView( context: ViewRepresentableContext < AnimatedImage > ) -> SDAnimatedImageView {
58- SDAnimatedImageView ( )
61+ func makeView( context: ViewRepresentableContext < AnimatedImage > ) -> AnimatedImageViewWrapper {
62+ AnimatedImageViewWrapper ( )
5963 }
6064
61- func updateView( _ view: SDAnimatedImageView , context: ViewRepresentableContext < AnimatedImage > ) {
62- view. image = imageModel. image
65+ func updateView( _ view: AnimatedImageViewWrapper , context: ViewRepresentableContext < AnimatedImage > ) {
66+ view. wrapped . image = imageModel. image
6367 if let url = imageModel. url {
64- view. sd_setImage ( with: url, placeholderImage: view . image , options: webOptions, context: webContext)
68+ view. wrapped . sd_setImage ( with: url, placeholderImage: nil , options: webOptions, context: webContext)
6569 }
6670
71+ layoutView ( view, context: context)
72+ }
73+
74+ func layoutView( _ view: AnimatedImageViewWrapper , context: ViewRepresentableContext < AnimatedImage > ) {
75+ // AspectRatio
76+ if let aspectRatio = imageLayout. aspectRatio {
77+ // Not implements
78+ }
79+ // ContentMode
6780 switch imageLayout. contentMode {
6881 case . fit:
6982 #if os(macOS)
70- view. imageScaling = . scaleProportionallyUpOrDown
83+ view. wrapped . imageScaling = . scaleProportionallyUpOrDown
7184 #else
72- view. contentMode = . scaleAspectFit
85+ view. wrapped . contentMode = . scaleAspectFit
7386 #endif
7487 case . fill:
7588 #if os(macOS)
76- view. imageScaling = . scaleAxesIndependently
89+ view. wrapped . imageScaling = . scaleAxesIndependently
7790 #else
78- view. contentMode = . scaleToFill
91+ view. wrapped . contentMode = . scaleToFill
7992 #endif
8093 }
94+ // RenderingMode
95+ if let renderingMode = imageLayout. renderingMode {
96+ switch renderingMode {
97+ case . template:
98+ #if os(macOS)
99+ view. wrapped. image? . isTemplate = true
100+ #else
101+ view. wrapped. image = view. wrapped. image? . withRenderingMode ( . alwaysTemplate)
102+ #endif
103+ case . original:
104+ #if os(macOS)
105+ view. wrapped. image? . isTemplate = false
106+ #else
107+ view. wrapped. image = view. wrapped. image? . withRenderingMode ( . alwaysOriginal)
108+ #endif
109+ @unknown default :
110+ // Future cases, not implements
111+ break
112+ }
113+ }
114+ // Interpolation
115+ if let interpolation = imageLayout. interpolation {
116+ switch interpolation {
117+ case . high:
118+ view. interpolationQuality = . high
119+ case . medium:
120+ view. interpolationQuality = . medium
121+ case . low:
122+ view. interpolationQuality = . low
123+ case . none:
124+ view. interpolationQuality = . none
125+ @unknown default :
126+ // Future cases, not implements
127+ break
128+ }
129+ } else {
130+ view. interpolationQuality = . default
131+ }
132+ // Antialiased
133+ view. shouldAntialias = imageLayout. antialiased
134+
135+ // Display
136+ #if os(macOS)
137+ view. updateConstraintsIfNeeded ( )
138+ view. needsDisplay = true
139+ #else
140+ view. updateConstraintsIfNeeded ( )
141+ view. setNeedsDisplay ( )
142+ #endif
81143 }
82144
83145 public func image( _ image: SDAnimatedImage ? ) -> Self {
@@ -90,15 +152,49 @@ public struct AnimatedImage : ViewRepresentable {
90152 return self
91153 }
92154
93- public func scaledToFit( ) -> Self {
94- imageLayout. contentMode = . fit
155+ public func resizable(
156+ capInsets: EdgeInsets = EdgeInsets ( ) ,
157+ resizingMode: Image . ResizingMode = . stretch) -> AnimatedImage
158+ {
159+ return self
160+ }
161+
162+ public func renderingMode( _ renderingMode: Image . TemplateRenderingMode ? ) -> AnimatedImage {
163+ imageLayout. renderingMode = renderingMode
164+ return self
165+ }
166+
167+ public func interpolation( _ interpolation: Image . Interpolation ) -> AnimatedImage {
168+ imageLayout. interpolation = interpolation
169+ return self
170+ }
171+
172+ public func antialiased( _ isAntialiased: Bool ) -> AnimatedImage {
173+ imageLayout. antialiased = isAntialiased
95174 return self
96175 }
97176
98- public func scaledToFill( ) -> Self {
99- imageLayout. contentMode = . fill
177+ public func aspectRatio( _ aspectRatio: CGFloat ? = nil , contentMode: ContentMode ) -> AnimatedImage {
178+ imageLayout. aspectRatio = aspectRatio
179+ imageLayout. contentMode = contentMode
100180 return self
101181 }
182+
183+ public func aspectRatio( _ aspectRatio: CGSize , contentMode: ContentMode ) -> AnimatedImage {
184+ var ratio : CGFloat ?
185+ if aspectRatio. width > 0 && aspectRatio. height > 0 {
186+ ratio = aspectRatio. width / aspectRatio. height
187+ }
188+ return self . aspectRatio ( ratio, contentMode: contentMode)
189+ }
190+
191+ public func scaledToFit( ) -> AnimatedImage {
192+ self . aspectRatio ( nil , contentMode: . fit)
193+ }
194+
195+ public func scaledToFill( ) -> AnimatedImage {
196+ self . aspectRatio ( nil , contentMode: . fill)
197+ }
102198}
103199
104200extension AnimatedImage {
@@ -123,4 +219,17 @@ extension AnimatedImage {
123219 }
124220}
125221
222+ #if DEBUG
223+ struct AnimatedImage_Previews : PreviewProvider {
224+ static var previews : some View {
225+ Group {
226+ AnimatedImage ( url: URL ( string: " http://assets.sbnation.com/assets/2512203/dogflops.gif " ) )
227+ . resizable ( )
228+ . aspectRatio ( contentMode: . fit)
229+ . padding ( )
230+ }
231+ }
232+ }
233+ #endif
234+
126235#endif
0 commit comments