فهرست منبع

Use a cleaner placeholder view

onevcat 4 سال پیش
والد
کامیت
54b375dd0a

+ 1 - 3
Demo/Demo/Kingfisher-Demo/SwiftUIViews/ListDemo.swift

@@ -43,8 +43,6 @@ struct ListDemo : View {
 @available(iOS 14.0, *)
 struct ImageCell: View {
 
-    @State var done = false
-
     var alreadyCached: Bool {
         ImageCache.default.isCached(forKey: url.absoluteString)
     }
@@ -57,7 +55,7 @@ struct ImageCell: View {
     var body: some View {
         HStack(alignment: .center) {
             Spacer()
-            KFImage.url(url, isLoaded: $done)
+            KFImage.url(url)
                 .resizable()
                 .onSuccess { r in
                     print("Success: \(self.index) - \(r.cacheType)")

+ 1 - 2
Demo/Demo/Kingfisher-Demo/SwiftUIViews/SingleViewDemo.swift

@@ -49,8 +49,7 @@ struct SingleViewDemo : View {
                     print("err: \(e)")
                 }
                 .placeholder { progress in
-                    Image(systemName: "arrow.2.circlepath.circle")
-                        .font(.largeTitle)
+                    ProgressView(progress)
                 }
                 .fade(duration: 1)
                 .forceTransition()

+ 1 - 5
Sources/SwiftUI/ImageBinder.swift

@@ -35,16 +35,13 @@ extension KFImage {
     /// image downloading and progress reporting based on `KingfisherManager`.
     class ImageBinder: ObservableObject {
         
-        init() {
-            isLoaded = .constant(false)
-        }
+        init() {}
 
         var downloadTask: DownloadTask?
 
         var loadingOrSucceeded: Bool {
             return downloadTask != nil || loadedImage != nil
         }
-        var isLoaded: Binding<Bool>
 
         @Published var loaded = false
         @Published var loadedImage: KFCrossPlatformImage? = nil
@@ -80,7 +77,6 @@ extension KFImage {
 
                             CallbackQueue.mainCurrentOrAsync.execute {
                                 self.loadedImage = value.image
-                                self.isLoaded.wrappedValue = true
                                 let animation = context.fadeTransitionDuration(cacheType: value.cacheType)
                                     .map { duration in Animation.linear(duration: duration) }
                                 withAnimation(animation) { self.loaded = true }

+ 3 - 0
Sources/SwiftUI/KFAnimatedImage.swift

@@ -71,6 +71,9 @@ struct KFAnimatedImage_Previews : PreviewProvider {
                 .onSuccess { r in
                     print(r)
                 }
+                .placeholder {
+                    ProgressView()
+                }
                 .padding()
         }
     }

+ 3 - 0
Sources/SwiftUI/KFImage.swift

@@ -76,6 +76,9 @@ struct KFImage_Previews : PreviewProvider {
                 .onSuccess { r in
                     print(r)
                 }
+                .placeholder { p in
+                    ProgressView(p)
+                }
                 .resizable()
                 .aspectRatio(contentMode: .fit)
                 .padding()

+ 15 - 33
Sources/SwiftUI/KFImageOptions.swift

@@ -35,29 +35,23 @@ extension KFImageProtocol {
     /// Creates a `KFImage` for a given `Source`.
     /// - Parameters:
     ///   - source: The `Source` object defines data information from network or a data provider.
-    ///   - isLoaded: Whether the image is loaded or not. This provides a way to inspect the internal loading
-    ///               state. `true` if the image is loaded successfully. Otherwise, `false`. Do not set the
-    ///               wrapped value from outside.
     /// - Returns: A `KFImage` for future configuration or embedding to a `SwiftUI.View`.
     public static func source(
-        _ source: Source?, isLoaded: Binding<Bool> = .constant(false)
+        _ source: Source?
     ) -> Self
     {
-        Self.init(source: source, isLoaded: isLoaded)
+        Self.init(source: source)
     }
 
     /// Creates a `KFImage` for a given `Resource`.
     /// - Parameters:
     ///   - source: The `Resource` object defines data information like key or URL.
-    ///   - isLoaded: Whether the image is loaded or not. This provides a way to inspect the internal loading
-    ///               state. `true` if the image is loaded successfully. Otherwise, `false`. Do not set the
-    ///               wrapped value from outside.
     /// - Returns: A `KFImage` for future configuration or embedding to a `SwiftUI.View`.
     public static func resource(
-        _ resource: Resource?, isLoaded: Binding<Bool> = .constant(false)
+        _ resource: Resource?
     ) -> Self
     {
-        source(resource?.convertToSource(), isLoaded: isLoaded)
+        source(resource?.convertToSource())
     }
 
     /// Creates a `KFImage` for a given `URL`.
@@ -65,47 +59,38 @@ extension KFImageProtocol {
     ///   - url: The URL where the image should be downloaded.
     ///   - cacheKey: The key used to store the downloaded image in cache.
     ///               If `nil`, the `absoluteString` of `url` is used as the cache key.
-    ///   - isLoaded: Whether the image is loaded or not. This provides a way to inspect the internal loading
-    ///               state. `true` if the image is loaded successfully. Otherwise, `false`. Do not set the
-    ///               wrapped value from outside.
     /// - Returns: A `KFImage` for future configuration or embedding to a `SwiftUI.View`.
     public static func url(
-        _ url: URL?, cacheKey: String? = nil, isLoaded: Binding<Bool> = .constant(false)
+        _ url: URL?, cacheKey: String? = nil
     ) -> Self
     {
-        source(url?.convertToSource(overrideCacheKey: cacheKey), isLoaded: isLoaded)
+        source(url?.convertToSource(overrideCacheKey: cacheKey))
     }
 
     /// Creates a `KFImage` for a given `ImageDataProvider`.
     /// - Parameters:
     ///   - provider: The `ImageDataProvider` object contains information about the data.
-    ///   - isLoaded: Whether the image is loaded or not. This provides a way to inspect the internal loading
-    ///               state. `true` if the image is loaded successfully. Otherwise, `false`. Do not set the
-    ///               wrapped value from outside.
     /// - Returns: A `KFImage` for future configuration or embedding to a `SwiftUI.View`.
     public static func dataProvider(
-        _ provider: ImageDataProvider?, isLoaded: Binding<Bool> = .constant(false)
+        _ provider: ImageDataProvider?
     ) -> Self
     {
-        source(provider?.convertToSource(), isLoaded: isLoaded)
+        source(provider?.convertToSource())
     }
 
     /// Creates a builder for some given raw data and a cache key.
     /// - Parameters:
     ///   - data: The data object from which the image should be created.
     ///   - cacheKey: The key used to store the downloaded image in cache.
-    ///   - isLoaded: Whether the image is loaded or not. This provides a way to inspect the internal loading
-    ///               state. `true` if the image is loaded successfully. Otherwise, `false`. Do not set the
-    ///               wrapped value from outside.
     /// - Returns: A `KFImage` for future configuration or embedding to a `SwiftUI.View`.
     public static func data(
-        _ data: Data?, cacheKey: String, isLoaded: Binding<Bool> = .constant(false)
+        _ data: Data?, cacheKey: String
     ) -> Self
     {
         if let data = data {
-            return dataProvider(RawImageDataProvider(data: data, cacheKey: cacheKey), isLoaded: isLoaded)
+            return dataProvider(RawImageDataProvider(data: data, cacheKey: cacheKey))
         } else {
-            return dataProvider(nil, isLoaded: isLoaded)
+            return dataProvider(nil)
         }
     }
 }
@@ -115,9 +100,9 @@ extension KFImageProtocol {
     /// Sets a placeholder `View` which shows when loading the image, with a progress parameter as input.
     /// - Parameter content: A view that describes the placeholder.
     /// - Returns: A `KFImage` view that contains `content` as its placeholder.
-    public func placeholder<Content: View>(@ViewBuilder _ content: @escaping (Progress) -> Content) -> Self {
+    public func placeholder<P: View>(@ViewBuilder _ content: @escaping (Progress) -> P) -> Self {
         context.placeholder = { progress in
-            AnyView(content(progress))
+            return AnyView(content(progress))
         }
         return self
     }
@@ -125,11 +110,8 @@ extension KFImageProtocol {
     /// Sets a placeholder `View` which shows when loading the image.
     /// - Parameter content: A view that describes the placeholder.
     /// - Returns: A `KFImage` view that contains `content` as its placeholder.
-    public func placeholder<Content: View>(@ViewBuilder _ content: @escaping () -> Content) -> Self {
-        context.placeholder = { _ in
-            AnyView(content())
-        }
-        return self
+    public func placeholder<P: View>(@ViewBuilder _ content: @escaping () -> P) -> Self {
+        placeholder { _ in content() }
     }
 
     /// Sets cancelling the download task bound to `self` when the view disappearing.

+ 3 - 9
Sources/SwiftUI/KFImageProtocol.swift

@@ -45,10 +45,7 @@ extension KFImageProtocol {
     /// Creates a Kingfisher compatible image view to load image from the given `Source`.
     /// - Parameters:
     ///   - source: The image `Source` defining where to load the target image.
-    ///   - isLoaded: Whether the image is loaded or not. This provides a way to inspect the internal loading
-    ///               state. `true` if the image is loaded successfully. Otherwise, `false`. Do not set the
-    ///               wrapped value from outside.
-    public init(source: Source?, isLoaded: Binding<Bool> = .constant(false)) {
+    public init(source: Source?) {
         let context = KFImage.Context<HoldingView>(source: source)
         self.init(context: context)
     }
@@ -56,11 +53,8 @@ extension KFImageProtocol {
     /// Creates a Kingfisher compatible image view to load image from the given `URL`.
     /// - Parameters:
     ///   - source: The image `Source` defining where to load the target image.
-    ///   - isLoaded: Whether the image is loaded or not. This provides a way to inspect the internal loading
-    ///               state. `true` if the image is loaded successfully. Otherwise, `false`. Do not set the
-    ///               wrapped value from outside.
-    public init(_ url: URL?, isLoaded: Binding<Bool> = .constant(false)) {
-        self.init(source: url?.convertToSource(), isLoaded: isLoaded)
+    public init(_ url: URL?) {
+        self.init(source: url?.convertToSource())
     }
     
     /// Configures current image with a `block`. This block will be lazily applied when creating the final `Image`.

+ 2 - 2
Sources/SwiftUI/KFImageRenderer.swift

@@ -46,8 +46,8 @@ struct KFImageRenderer<HoldingView> : View where HoldingView: KFImageHoldingView
                     .opacity(binder.loaded ? 1.0 : 0.0)
             } else {
                 Group {
-                    if let placeholder = context.placeholder {
-                        placeholder(binder.progress)
+                    if let placeholder = context.placeholder, let view = placeholder(binder.progress) {
+                        view
                     } else {
                         Color.clear
                     }