Просмотр исходного кода

Expose configurable animated image view

onevcat 4 лет назад
Родитель
Сommit
08b775628d

+ 3 - 0
Demo/Demo/Kingfisher-Demo/SwiftUIViews/AnimatedImageDemo.swift

@@ -39,6 +39,9 @@ struct AnimatedImageDemo: View {
     var body: some View {
         VStack {
             KFAnimatedImage(url)
+                .configure { view in
+                    view.framePreloadCount = 3
+                }
                 .cacheOriginalImage()
                 .onSuccess { r in
                     print("suc: \(r)")

+ 1 - 0
Sources/SwiftUI/ImageContext.swift

@@ -37,6 +37,7 @@ extension KFImage {
         )
 
         var configurations: [(HoldingView) -> HoldingView] = []
+        var renderConfigurations: [(HoldingView.RenderingView) -> Void] = []
         
         var cancelOnDisappear: Bool = false
         var placeholder: ((Progress) -> AnyView)? = nil

+ 17 - 2
Sources/SwiftUI/KFAnimatedImage.swift

@@ -35,19 +35,34 @@ public struct KFAnimatedImage: KFImageProtocol {
     public init(context: KFImage.Context<HoldingView>) {
         self.context = context
     }
+    
+    /// Configures current rendering view with a `block`. This block will be applied when the under-hood
+    /// `AnimatedImageView` is created in `UIViewRepresentable.makeUIView(context:)`
+    ///
+    /// - Parameter block: The block applies to the animated image view.
+    /// - Returns: A `KFAnimatedImage` view that being configured by the `block`.
+    public func configure(_ block: @escaping (HoldingView.RenderingView) -> Void) -> Self {
+        context.renderConfigurations.append(block)
+        return self
+    }
 }
 
 /// A wrapped `UIViewRepresentable` of `AnimatedImageView`
 @available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *)
 public struct KFAnimatedImageViewRepresenter: UIViewRepresentable, KFImageHoldingView {
-    public static func created(from image: KFCrossPlatformImage?) -> KFAnimatedImageViewRepresenter {
-        KFAnimatedImageViewRepresenter(image: image)
+    public typealias RenderingView = AnimatedImageView
+    public static func created(from image: KFCrossPlatformImage?, context: KFImage.Context<Self>) -> KFAnimatedImageViewRepresenter {
+        KFAnimatedImageViewRepresenter(image: image, context: context)
     }
     
     var image: KFCrossPlatformImage?
+    let context: KFImage.Context<KFAnimatedImageViewRepresenter>
     
     public func makeUIView(context: Context) -> AnimatedImageView {
         let view = AnimatedImageView()
+        
+        self.context.renderConfigurations.forEach { $0(view) }
+        
         view.image = image
         
         // Allow SwiftUI scale (fit/fill) working fine.

+ 2 - 1
Sources/SwiftUI/KFImage.swift

@@ -38,7 +38,8 @@ public struct KFImage: KFImageProtocol {
 
 @available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *)
 extension Image: KFImageHoldingView {
-    public static func created(from image: KFCrossPlatformImage?) -> Image {
+    public typealias RenderingView = Image
+    public static func created(from image: KFCrossPlatformImage?, context: KFImage.Context<Self>) -> Image {
         Image(crossPlatformImage: image)
     }
 }

+ 2 - 1
Sources/SwiftUI/KFImageProtocol.swift

@@ -68,7 +68,8 @@ extension KFImageProtocol {
 
 @available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *)
 public protocol KFImageHoldingView: View {
-    static func created(from image: KFCrossPlatformImage?) -> Self
+    associatedtype RenderingView
+    static func created(from image: KFCrossPlatformImage?, context: KFImage.Context<Self>) -> Self
 }
 
 @available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *)

+ 1 - 1
Sources/SwiftUI/KFImageRenderer.swift

@@ -40,7 +40,7 @@ struct KFImageRenderer<HoldingView> : View where HoldingView: KFImageHoldingView
         
         ZStack {
             context.configurations
-                .reduce(HoldingView.created(from: binder.loadedImage)) {
+                .reduce(HoldingView.created(from: binder.loadedImage, context: context)) {
                     current, config in config(current)
                 }
                 .opacity(binder.loaded ? 1.0 : 0.0)

+ 0 - 1
Sources/Views/AnimatedImageView.swift

@@ -68,7 +68,6 @@ let KFRunLoopModeCommon = RunLoop.Mode.common
 /// Kingfisher supports setting GIF animated data to either `UIImageView` and `AnimatedImageView` out of box. So
 /// it would be fairly easy to switch between them.
 open class AnimatedImageView: UIImageView {
-    
     /// Proxy object for preventing a reference cycle between the `CADDisplayLink` and `AnimatedImageView`.
     class TargetProxy {
         private weak var target: AnimatedImageView?