Browse Source

Use ZStack for image setting now all using the same view id

onevcat 4 years ago
parent
commit
085198f607

+ 1 - 0
Demo/Demo/Kingfisher-Demo/SwiftUIViews/MainView.swift

@@ -47,6 +47,7 @@ struct MainView: View {
             NavigationLink(destination: GridDemo()) { Text("Grid") }
             NavigationLink(destination: AnimatedImageDemo()) { Text("Animated Image") }
             NavigationLink(destination: GeometryReaderDemo()) { Text("Geometry Reader") }
+            NavigationLink(destination: TransitionViewDemo()) { Text("Transition") }
         }.navigationBarTitle(Text("SwiftUI Sample"))
     }
 }

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

@@ -51,7 +51,7 @@ struct SingleViewDemo : View {
                 .placeholder { progress in
                     ProgressView(progress)
                 }
-                .fade(duration: 1)
+                .fade(duration: index == 1 ? 0 : 1) // Do not animate for the first image. Otherwise it causes an unwanted animation when the page is shown.
                 .forceTransition()
                 .resizable()
                 .frame(width: 300, height: 300)

+ 55 - 0
Demo/Demo/Kingfisher-Demo/SwiftUIViews/TransitionViewDemo.swift

@@ -0,0 +1,55 @@
+//
+//  TransitionViewDemo.swift
+//  Kingfisher
+//
+//  Created by onevcat on 2021/08/03.
+//
+//  Copyright (c) 2021 Wei Wang <onevcat@gmail.com>
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+
+import SwiftUI
+import Kingfisher
+
+@available(iOS 14.0, *)
+struct TransitionViewDemo: View {
+    @State private var showDetails = false
+    
+    var body: some View {
+        VStack {
+            Button(showDetails ? "Hide" : "Show") {
+                withAnimation {
+                    showDetails.toggle()
+                }
+            }
+            if showDetails {
+                KFImage(ImageLoader.sampleImageURLs.first)
+                    .transition(.slide)
+            }
+            Spacer()
+        }.frame(height: 500)
+    }
+}
+
+@available(iOS 14.0, *)
+struct TransitionViewDemo_Previews: PreviewProvider {
+    static var previews: some View {
+        TransitionViewDemo()
+    }
+}

+ 4 - 0
Demo/Kingfisher-Demo.xcodeproj/project.pbxproj

@@ -13,6 +13,7 @@
 		277EAE9D2045B4D500547CD3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 277EAE962045B4D500547CD3 /* Assets.xcassets */; };
 		277EAEA12045B52800547CD3 /* InterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 277EAE9E2045B52800547CD3 /* InterfaceController.swift */; };
 		277EAEA32045B52800547CD3 /* ExtensionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 277EAEA02045B52800547CD3 /* ExtensionDelegate.swift */; };
+		4B120CA726B91BB70060B092 /* TransitionViewDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B120CA626B91BB70060B092 /* TransitionViewDemo.swift */; };
 		4B1C7A3D21A256E300CE9D31 /* InfinityCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B1C7A3C21A256E300CE9D31 /* InfinityCollectionViewController.swift */; };
 		4B4307A51D87E6A700ED2DA9 /* loader.gif in Resources */ = {isa = PBXBuildFile; fileRef = 4B7742461D87E42E0077024E /* loader.gif */; };
 		4B7742471D87E42E0077024E /* loader.gif in Resources */ = {isa = PBXBuildFile; fileRef = 4B7742461D87E42E0077024E /* loader.gif */; };
@@ -158,6 +159,7 @@
 		277EAE9E2045B52800547CD3 /* InterfaceController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InterfaceController.swift; sourceTree = "<group>"; };
 		277EAE9F2045B52800547CD3 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
 		277EAEA02045B52800547CD3 /* ExtensionDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExtensionDelegate.swift; sourceTree = "<group>"; };
+		4B120CA626B91BB70060B092 /* TransitionViewDemo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransitionViewDemo.swift; sourceTree = "<group>"; };
 		4B1C7A3C21A256E300CE9D31 /* InfinityCollectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfinityCollectionViewController.swift; sourceTree = "<group>"; };
 		4B2944551C3D03880088C3E7 /* Kingfisher-macOS-Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Kingfisher-macOS-Demo.app"; sourceTree = BUILT_PRODUCTS_DIR; };
 		4B7742461D87E42E0077024E /* loader.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = loader.gif; sourceTree = "<group>"; };
@@ -421,6 +423,7 @@
 				D198F42125EDC4B900C53E0D /* GridDemo.swift */,
 				4B779C8426743C2800FF9C1E /* GeometryReaderDemo.swift */,
 				D1F78A632589F17200930759 /* SingleViewDemo.swift */,
+				4B120CA626B91BB70060B092 /* TransitionViewDemo.swift */,
 				D198F41D25EDC11500C53E0D /* LazyVStackDemo.swift */,
 				D198F41F25EDC34000C53E0D /* SizingAnimationDemo.swift */,
 				072922422638639D0089E810 /* AnimatedImageDemo.swift */,
@@ -697,6 +700,7 @@
 				4B1C7A3D21A256E300CE9D31 /* InfinityCollectionViewController.swift in Sources */,
 				D1A1CCA321A1879600263AD8 /* MainViewController.swift in Sources */,
 				D1F06F3721AAEACF000B1C38 /* GIFViewController.swift in Sources */,
+				4B120CA726B91BB70060B092 /* TransitionViewDemo.swift in Sources */,
 				769F07F126298E2E00610767 /* GIFHeavyViewController.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;

+ 1 - 1
Sources/SwiftUI/KFAnimatedImage.swift

@@ -40,7 +40,7 @@ public struct KFAnimatedImage: KFImageProtocol {
 /// 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 {
+    public static func created(from image: KFCrossPlatformImage?) -> KFAnimatedImageViewRepresenter {
         KFAnimatedImageViewRepresenter(image: image)
     }
     

+ 1 - 1
Sources/SwiftUI/KFImage.swift

@@ -38,7 +38,7 @@ 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 static func created(from image: KFCrossPlatformImage?) -> Image {
         Image(crossPlatformImage: image)
     }
 }

+ 1 - 1
Sources/SwiftUI/KFImageProtocol.swift

@@ -68,7 +68,7 @@ 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
+    static func created(from image: KFCrossPlatformImage?) -> Self
 }
 
 @available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *)

+ 11 - 11
Sources/SwiftUI/KFImageRenderer.swift

@@ -37,14 +37,14 @@ struct KFImageRenderer<HoldingView> : View where HoldingView: KFImageHoldingView
     let context: KFImage.Context<HoldingView>
     
     var body: some View {
-        Group {
-            if let image = binder.loadedImage {
-                context.configurations
-                    .reduce(HoldingView.created(from: image)) {
-                        current, config in config(current)
-                    }
-                    .opacity(binder.loaded ? 1.0 : 0.0)
-            } else {
+        
+        ZStack {
+            context.configurations
+                .reduce(HoldingView.created(from: binder.loadedImage)) {
+                    current, config in config(current)
+                }
+                .opacity(binder.loaded ? 1.0 : 0.0)
+            if binder.loadedImage == nil {
                 Group {
                     if let placeholder = context.placeholder, let view = placeholder(binder.progress) {
                         view
@@ -76,11 +76,11 @@ struct KFImageRenderer<HoldingView> : View where HoldingView: KFImageHoldingView
 @available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *)
 extension Image {
     // Creates an Image with either UIImage or NSImage.
-    init(crossPlatformImage: KFCrossPlatformImage) {
+    init(crossPlatformImage: KFCrossPlatformImage?) {
         #if canImport(UIKit)
-        self.init(uiImage: crossPlatformImage)
+        self.init(uiImage: crossPlatformImage ?? KFCrossPlatformImage())
         #elseif canImport(AppKit)
-        self.init(nsImage: crossPlatformImage)
+        self.init(nsImage: crossPlatformImage ?? KFCrossPlatformImage())
         #endif
     }
 }