diff --git a/Example/SDWebImageSwiftUIDemo/ContentView.swift b/Example/SDWebImageSwiftUIDemo/ContentView.swift index effa25f..4e602f3 100644 --- a/Example/SDWebImageSwiftUIDemo/ContentView.swift +++ b/Example/SDWebImageSwiftUIDemo/ContentView.swift @@ -16,10 +16,10 @@ struct ContentView: View { VStack { WebImage(url: URL(string: "https://nokiatech.github.io/heif/content/images/ski_jump_1440x960.heic")) .scaledToFit() - .frame(width: 300, height: 300, alignment: .center) - AnimatedImage(url: URL(string: "https://raw.githubusercontent.com/liyong03/YLGIFImage/master/YLGIFImageDemo/YLGIFImageDemo/joy.gif")) -// .scaledToFit() // Apple's Bug ? Custom UIView does not passthrough the `contentMode` from Swift UI layout system into UIKit layout system - .frame(width: 400, height: 300, alignment: .center) + .frame(width: CGFloat(300), height: CGFloat(300), alignment: .center) + AnimatedImage(url: URL(string: "https://raw.githubusercontent.com/liyong03/YLGIFImage/master/YLGIFImageDemo/YLGIFImageDemo/joy.gif"), options: [.progressiveLoad]) + .scaledToFill() + .frame(width: CGFloat(400), height: CGFloat(300), alignment: .center) } } } diff --git a/SDWebImageSwiftUI/Classes/AnimatedImage.swift b/SDWebImageSwiftUI/Classes/AnimatedImage.swift index a3e1175..446c192 100644 --- a/SDWebImageSwiftUI/Classes/AnimatedImage.swift +++ b/SDWebImageSwiftUI/Classes/AnimatedImage.swift @@ -11,12 +11,24 @@ import SDWebImage #if !os(watchOS) -public struct AnimatedImage: ViewRepresentable { - var url: URL? - var name: String? - var bundle: Bundle? - var data: Data? - var scale: CGFloat = 0 +// Data Binding Object +final class AnimatedImageModel : ObservableObject { + @Published var image: SDAnimatedImage? + @Published var url: URL? +} + +// Layout Binding Object +final class AnimatedImageLayout : ObservableObject { + @Published var contentMode: ContentMode = .fill +} + +// View +public struct AnimatedImage : ViewRepresentable { + @ObservedObject var imageModel = AnimatedImageModel() + @ObservedObject var imageLayout = AnimatedImageLayout() + + var webOptions: SDWebImageOptions = [] + var webContext: [SDWebImageContextOption : Any]? = nil #if os(macOS) public typealias NSViewType = SDAnimatedImageView @@ -47,36 +59,67 @@ public struct AnimatedImage: ViewRepresentable { } func updateView(_ view: SDAnimatedImageView, context: ViewRepresentableContext) { - if let url = url { - view.sd_setImage(with: url) - return + view.image = imageModel.image + if let url = imageModel.url { + view.sd_setImage(with: url, placeholderImage: view.image, options: webOptions, context: webContext) } - if let name = name { + + switch imageLayout.contentMode { + case .fit: #if os(macOS) - view.image = SDAnimatedImage(named: name, in: bundle) + view.imageScaling = .scaleProportionallyUpOrDown #else - view.image = SDAnimatedImage(named: name, in: bundle, compatibleWith: nil) + view.contentMode = .scaleAspectFit + #endif + case .fill: + #if os(macOS) + view.imageScaling = .scaleAxesIndependently + #else + view.contentMode = .scaleToFill #endif - return - } - if let data = data { - view.image = SDAnimatedImage(data: data, scale: scale) - return } } - public init(url: URL?, placeholder: Image? = nil, options: SDWebImageOptions = [], context: [SDWebImageContextOption : Any]? = nil) { - self.url = url + public func image(_ image: SDAnimatedImage?) -> Self { + imageModel.image = image + return self } + public func imageUrl(_ url: URL?) -> Self { + imageModel.url = url + return self + } + + public func scaledToFit() -> Self { + imageLayout.contentMode = .fit + return self + } + + public func scaledToFill() -> Self { + imageLayout.contentMode = .fill + return self + } +} + +extension AnimatedImage { + public init(url: URL?, placeholder: SDAnimatedImage? = nil, options: SDWebImageOptions = [], context: [SDWebImageContextOption : Any]? = nil) { + self.webOptions = options + self.webContext = context + self.imageModel.url = url + } + public init(name: String, bundle: Bundle? = nil) { - self.name = name - self.bundle = bundle + #if os(macOS) + let image = SDAnimatedImage(named: name, in: bundle) + #else + let image = SDAnimatedImage(named: name, in: bundle, compatibleWith: nil) + #endif + self.imageModel.image = image } - + public init(data: Data, scale: CGFloat = 0) { - self.data = data - self.scale = scale + let image = SDAnimatedImage(data: data, scale: scale) + self.imageModel.image = image } }