diff --git a/Demo/Demo/Kingfisher-Demo/SwiftUIViews/AnimatedImageDemo.swift b/Demo/Demo/Kingfisher-Demo/SwiftUIViews/AnimatedImageDemo.swift index e32bff977..7bab3882e 100644 --- a/Demo/Demo/Kingfisher-Demo/SwiftUIViews/AnimatedImageDemo.swift +++ b/Demo/Demo/Kingfisher-Demo/SwiftUIViews/AnimatedImageDemo.swift @@ -27,7 +27,7 @@ import SwiftUI import Kingfisher -@available(iOS 13.0, *) +@available(iOS 14.0, *) struct AnimatedImageDemo: View { @State private var index = 1 @@ -66,7 +66,7 @@ struct AnimatedImageDemo: View { } -@available(iOS 13.0, *) +@available(iOS 14.0, *) struct AnimatedImageDemo_Previews: PreviewProvider { static var previews: some View { diff --git a/Demo/Demo/Kingfisher-Demo/SwiftUIViews/GeometryReaderDemo.swift b/Demo/Demo/Kingfisher-Demo/SwiftUIViews/GeometryReaderDemo.swift new file mode 100644 index 000000000..7d00b4ef8 --- /dev/null +++ b/Demo/Demo/Kingfisher-Demo/SwiftUIViews/GeometryReaderDemo.swift @@ -0,0 +1,51 @@ +// +// GeometryReaderDemo.swift +// Kingfisher +// +// Created by JP20028 on 2021/06/12. +// +// Copyright (c) 2021 Wei Wang +// +// 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 GeometryReaderDemo: View { + var body: some View { + GeometryReader { geo in + KFImage( + ImageLoader.sampleImageURLs.first + ) + .placeholder { ProgressView() } + .forceRefresh() + .resizable() + .scaledToFit() + .frame(width: geo.size.width) + } + } +} + +@available(iOS 14.0, *) +struct GeometryReaderDemo_Previews: PreviewProvider { + static var previews: some View { + GeometryReaderDemo() + } +} diff --git a/Demo/Demo/Kingfisher-Demo/SwiftUIViews/ListDemo.swift b/Demo/Demo/Kingfisher-Demo/SwiftUIViews/ListDemo.swift index e5777fc21..9891a0908 100644 --- a/Demo/Demo/Kingfisher-Demo/SwiftUIViews/ListDemo.swift +++ b/Demo/Demo/Kingfisher-Demo/SwiftUIViews/ListDemo.swift @@ -27,7 +27,7 @@ import Kingfisher import SwiftUI -@available(iOS 13.0, *) +@available(iOS 14.0, *) struct ListDemo : View { let index = 1 ..< 700 @@ -40,7 +40,7 @@ struct ListDemo : View { } } -@available(iOS 13.0, *) +@available(iOS 14.0, *) struct ImageCell: View { @State var done = false @@ -89,7 +89,7 @@ struct ImageCell: View { } -@available(iOS 13.0, *) +@available(iOS 14.0, *) struct SwiftUIList_Previews : PreviewProvider { static var previews: some View { ListDemo() diff --git a/Demo/Demo/Kingfisher-Demo/SwiftUIViews/MainView.swift b/Demo/Demo/Kingfisher-Demo/SwiftUIViews/MainView.swift index 91123f6df..075a50e7a 100644 --- a/Demo/Demo/Kingfisher-Demo/SwiftUIViews/MainView.swift +++ b/Demo/Demo/Kingfisher-Demo/SwiftUIViews/MainView.swift @@ -27,7 +27,7 @@ import SwiftUI import Kingfisher -@available(iOS 13.0, *) +@available(iOS 14.0, *) struct MainView: View { var body: some View { List { @@ -43,16 +43,15 @@ struct MainView: View { NavigationLink(destination: SingleViewDemo()) { Text("Basic Image") } NavigationLink(destination: SizingAnimationDemo()) { Text("Sizing Toggle") } NavigationLink(destination: ListDemo()) { Text("List") } - if #available(iOS 14.0, *) { - NavigationLink(destination: LazyVStackDemo()) { Text("Stack") } - NavigationLink(destination: GridDemo()) { Text("Grid") } - } + NavigationLink(destination: LazyVStackDemo()) { Text("Stack") } + NavigationLink(destination: GridDemo()) { Text("Grid") } NavigationLink(destination: AnimatedImageDemo()) { Text("Animated Image") } + NavigationLink(destination: GeometryReaderDemo()) { Text("Geometry Reader") } }.navigationBarTitle(Text("SwiftUI Sample")) } } -@available(iOS 13.0, *) +@available(iOS 14.0, *) struct MainView_Previews: PreviewProvider { static var previews: some View { MainView() diff --git a/Demo/Demo/Kingfisher-Demo/SwiftUIViews/SingleViewDemo.swift b/Demo/Demo/Kingfisher-Demo/SwiftUIViews/SingleViewDemo.swift index 44a73c66b..f863c0b15 100644 --- a/Demo/Demo/Kingfisher-Demo/SwiftUIViews/SingleViewDemo.swift +++ b/Demo/Demo/Kingfisher-Demo/SwiftUIViews/SingleViewDemo.swift @@ -27,7 +27,7 @@ import Kingfisher import SwiftUI -@available(iOS 13.0, *) +@available(iOS 14.0, *) struct SingleViewDemo : View { @State private var index = 1 @@ -72,7 +72,7 @@ struct SingleViewDemo : View { } } -@available(iOS 13.0, *) +@available(iOS 14.0, *) struct SingleViewDemo_Previews : PreviewProvider { static var previews: some View { SingleViewDemo() diff --git a/Demo/Demo/Kingfisher-Demo/SwiftUIViews/SizingAnimationDemo.swift b/Demo/Demo/Kingfisher-Demo/SwiftUIViews/SizingAnimationDemo.swift index c043a66b3..3f11cb4f6 100644 --- a/Demo/Demo/Kingfisher-Demo/SwiftUIViews/SizingAnimationDemo.swift +++ b/Demo/Demo/Kingfisher-Demo/SwiftUIViews/SizingAnimationDemo.swift @@ -27,7 +27,7 @@ import SwiftUI import Kingfisher -@available(iOS 13.0, *) +@available(iOS 14.0, *) struct SizingAnimationDemo: View { @State var imageSize: CGFloat = 250 @State var isPlaying = false @@ -62,7 +62,7 @@ struct SizingAnimationDemo: View { } } -@available(iOS 13.0, *) +@available(iOS 14.0, *) struct SizingAnimationDemo_Previews: PreviewProvider { static var previews: some View { SizingAnimationDemo() diff --git a/Demo/Demo/Kingfisher-Demo/ViewControllers/SwiftUIViewController.swift b/Demo/Demo/Kingfisher-Demo/ViewControllers/SwiftUIViewController.swift index 0c1c6397e..41c30de5b 100644 --- a/Demo/Demo/Kingfisher-Demo/ViewControllers/SwiftUIViewController.swift +++ b/Demo/Demo/Kingfisher-Demo/ViewControllers/SwiftUIViewController.swift @@ -27,7 +27,7 @@ import SwiftUI import UIKit -@available(iOS 13.0, *) +@available(iOS 14.0, *) class SwiftUIViewController: UIHostingController { required init?(coder: NSCoder) { super.init(coder: coder, rootView: MainView()) diff --git a/Demo/Kingfisher-Demo.xcodeproj/project.pbxproj b/Demo/Kingfisher-Demo.xcodeproj/project.pbxproj index 28a36bba3..126c81da2 100644 --- a/Demo/Kingfisher-Demo.xcodeproj/project.pbxproj +++ b/Demo/Kingfisher-Demo.xcodeproj/project.pbxproj @@ -17,6 +17,7 @@ 4B4307A51D87E6A700ED2DA9 /* loader.gif in Resources */ = {isa = PBXBuildFile; fileRef = 4B7742461D87E42E0077024E /* loader.gif */; }; 4B7742471D87E42E0077024E /* loader.gif in Resources */ = {isa = PBXBuildFile; fileRef = 4B7742461D87E42E0077024E /* loader.gif */; }; 4B7742481D87E42E0077024E /* loader.gif in Resources */ = {isa = PBXBuildFile; fileRef = 4B7742461D87E42E0077024E /* loader.gif */; }; + 4B779C8526743C2800FF9C1E /* GeometryReaderDemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B779C8426743C2800FF9C1E /* GeometryReaderDemo.swift */; }; 4B92FE5625FF906B00473088 /* AutoSizingTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92FE5525FF906B00473088 /* AutoSizingTableViewController.swift */; }; 4BCCF33D1D5B02F8003387C2 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BCCF3361D5B02F8003387C2 /* AppDelegate.swift */; }; 4BCCF33E1D5B02F8003387C2 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4BCCF3371D5B02F8003387C2 /* Assets.xcassets */; }; @@ -158,6 +159,7 @@ 4B1C7A3C21A256E300CE9D31 /* InfinityCollectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfinityCollectionViewController.swift; sourceTree = ""; }; 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 = ""; }; + 4B779C8426743C2800FF9C1E /* GeometryReaderDemo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeometryReaderDemo.swift; sourceTree = ""; }; 4B92FE5525FF906B00473088 /* AutoSizingTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoSizingTableViewController.swift; sourceTree = ""; }; 4BCCF3361D5B02F8003387C2 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 4BCCF3371D5B02F8003387C2 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; @@ -413,6 +415,7 @@ D1F78A622589F17200930759 /* MainView.swift */, D1F78A612589F17200930759 /* ListDemo.swift */, D198F42125EDC4B900C53E0D /* GridDemo.swift */, + 4B779C8426743C2800FF9C1E /* GeometryReaderDemo.swift */, D1F78A632589F17200930759 /* SingleViewDemo.swift */, D198F41D25EDC11500C53E0D /* LazyVStackDemo.swift */, D198F41F25EDC34000C53E0D /* SizingAnimationDemo.swift */, @@ -680,6 +683,7 @@ D1E4CF5421BACBA6004D029D /* ImageDataProviderCollectionViewController.swift in Sources */, D1FAB06F21A853E600908910 /* HighResolutionCollectionViewController.swift in Sources */, D1F78A652589F17200930759 /* MainView.swift in Sources */, + 4B779C8526743C2800FF9C1E /* GeometryReaderDemo.swift in Sources */, D1F78A5F2589F0AA00930759 /* SwiftUIViewController.swift in Sources */, D12E0C951C47F91800AC98AD /* AppDelegate.swift in Sources */, D1F06F3321AA4292000B1C38 /* DetailImageViewController.swift in Sources */, diff --git a/Sources/SwiftUI/ImageBinder.swift b/Sources/SwiftUI/ImageBinder.swift index cd4aac152..3ba2c3e5c 100644 --- a/Sources/SwiftUI/ImageBinder.swift +++ b/Sources/SwiftUI/ImageBinder.swift @@ -26,8 +26,9 @@ #if canImport(SwiftUI) && canImport(Combine) import SwiftUI +import Combine -@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) +@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) extension KFImage { /// Represents a binder for `KFImage`. It takes responsibility as an `ObjectBinding` and performs @@ -139,7 +140,7 @@ extension KFImage { } } -@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) +@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) extension KFImage.ImageBinder: Hashable { static func == (lhs: KFImage.ImageBinder, rhs: KFImage.ImageBinder) -> Bool { lhs.source == rhs.source && lhs.options.processor.identifier == rhs.options.processor.identifier diff --git a/Sources/SwiftUI/ImageContext.swift b/Sources/SwiftUI/ImageContext.swift index edd3ed70a..abfd04b1a 100644 --- a/Sources/SwiftUI/ImageContext.swift +++ b/Sources/SwiftUI/ImageContext.swift @@ -26,8 +26,9 @@ #if canImport(SwiftUI) && canImport(Combine) import SwiftUI +import Combine -@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) +@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) extension KFImage { public struct Context { var binder: ImageBinder @@ -42,7 +43,7 @@ extension KFImage { } #if canImport(UIKit) && !os(watchOS) -@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) +@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) extension KFAnimatedImage { public typealias Context = KFImage.Context typealias ImageBinder = KFImage.ImageBinder diff --git a/Sources/SwiftUI/KFAnimatedImage.swift b/Sources/SwiftUI/KFAnimatedImage.swift index e968ea972..816a773e3 100644 --- a/Sources/SwiftUI/KFAnimatedImage.swift +++ b/Sources/SwiftUI/KFAnimatedImage.swift @@ -26,8 +26,9 @@ #if canImport(SwiftUI) && canImport(Combine) && canImport(UIKit) && !os(watchOS) import SwiftUI +import Combine -@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) +@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) public struct KFAnimatedImage: KFImageProtocol { public typealias HoldingView = KFAnimatedImageViewRepresenter public var context: Context @@ -37,7 +38,7 @@ public struct KFAnimatedImage: KFImageProtocol { } /// A wrapped `UIViewRepresentable` of `AnimatedImageView` -@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) +@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) @@ -62,7 +63,7 @@ public struct KFAnimatedImageViewRepresenter: UIViewRepresentable, KFImageHoldin } #if DEBUG -@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) +@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) struct KFAnimatedImage_Previews : PreviewProvider { static var previews: some View { Group { diff --git a/Sources/SwiftUI/KFImage.swift b/Sources/SwiftUI/KFImage.swift index ca2e7593c..15117815d 100644 --- a/Sources/SwiftUI/KFImage.swift +++ b/Sources/SwiftUI/KFImage.swift @@ -26,8 +26,9 @@ #if canImport(SwiftUI) && canImport(Combine) import SwiftUI +import Combine -@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) +@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) public struct KFImage: KFImageProtocol { public var context: Context public init(context: Context) { @@ -35,35 +36,15 @@ public struct KFImage: KFImageProtocol { } } -@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) +@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) extension Image: KFImageHoldingView { public static func created(from image: KFCrossPlatformImage) -> Image { - if #available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *) { - return Image(crossPlatformImage: image) - } else { - #if canImport(UIKit) - // The CG image is used to solve #1395 - // It should be not necessary if SwiftUI.Image can handle resizing correctly when created - // by `Image.init(uiImage:)`. (The orientation information should be already contained in - // a `UIImage`) - // https://github.com/onevcat/Kingfisher/issues/1395 - // - // This issue happens on iOS 13 and was fixed by Apple from iOS 14. - if let cgImage = image.cgImage { - return Image(decorative: cgImage, scale: image.scale, orientation: image.imageOrientation.toSwiftUI()) - } else { - return Image(crossPlatformImage: image) - } - #else - return Image(crossPlatformImage: image) - #endif - - } + Image(crossPlatformImage: image) } } // MARK: - Image compatibility. -@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) +@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) extension KFImage { public func resizable( @@ -87,7 +68,7 @@ extension KFImage { } // MARK: - Deprecated -@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) +@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) extension KFImage { /// Creates a Kingfisher compatible image view to load image from the given `Source`. /// - Parameter source: The image `Source` defining where to load the target image. @@ -122,7 +103,7 @@ extension KFImage { } #if DEBUG -@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) +@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) struct KFImage_Previews : PreviewProvider { static var previews: some View { Group { diff --git a/Sources/SwiftUI/KFImageOptions.swift b/Sources/SwiftUI/KFImageOptions.swift index 2a3c553ed..4d132a676 100644 --- a/Sources/SwiftUI/KFImageOptions.swift +++ b/Sources/SwiftUI/KFImageOptions.swift @@ -26,9 +26,10 @@ #if canImport(SwiftUI) && canImport(Combine) import SwiftUI +import Combine // MARK: - KFImage creating. -@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) +@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) extension KFImageProtocol { /// Creates a `KFImage` for a given `Source`. @@ -109,7 +110,7 @@ extension KFImageProtocol { } } -@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) +@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) extension KFImageProtocol { /// Sets a placeholder `View` which shows when loading the image. /// - Parameter content: A view that describes the placeholder. diff --git a/Sources/SwiftUI/KFImageProtocol.swift b/Sources/SwiftUI/KFImageProtocol.swift index 230236d89..2b5a2d362 100644 --- a/Sources/SwiftUI/KFImageProtocol.swift +++ b/Sources/SwiftUI/KFImageProtocol.swift @@ -26,18 +26,24 @@ #if canImport(SwiftUI) && canImport(Combine) import SwiftUI +import Combine -@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) +@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) public protocol KFImageProtocol: View, KFOptionSetter { associatedtype HoldingView: KFImageHoldingView var context: KFImage.Context { get set } init(context: KFImage.Context) } -@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) +@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) extension KFImageProtocol { public var body: some View { - KFImageRenderer(context) + KFImageRenderer( + binder: context.binder, + placeholder: context.placeholder, + cancelOnDisappear: context.cancelOnDisappear, + configurations: context.configurations + ) .id(context.binder) } @@ -91,12 +97,12 @@ extension KFImageProtocol { } } -@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) +@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) public protocol KFImageHoldingView: View { static func created(from image: KFCrossPlatformImage) -> Self } -@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) +@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) extension KFImageProtocol { public var options: KingfisherParsedOptionsInfo { get { context.binder.options } diff --git a/Sources/SwiftUI/KFImageRenderer.swift b/Sources/SwiftUI/KFImageRenderer.swift index 4d12fff07..8a5fd55b3 100644 --- a/Sources/SwiftUI/KFImageRenderer.swift +++ b/Sources/SwiftUI/KFImageRenderer.swift @@ -26,14 +26,15 @@ #if canImport(SwiftUI) && canImport(Combine) import SwiftUI +import Combine /// A Kingfisher compatible SwiftUI `View` to load an image from a `Source`. /// Declaring a `KFImage` in a `View`'s body to trigger loading from the given `Source`. -@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) +@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) struct KFImageRenderer : View where HoldingView: KFImageHoldingView { /// An image binder that manages loading and cancelling image related task. - @ObservedObject var binder: KFImage.ImageBinder + @StateObject var binder: KFImage.ImageBinder // Acts as a placeholder when loading an image. var placeholder: AnyView? @@ -44,13 +45,6 @@ struct KFImageRenderer : View where HoldingView: KFImageHoldingView // Configurations should be performed on the image. let configurations: [(HoldingView) -> HoldingView] - init(_ context: KFImage.Context) { - self.binder = context.binder - self.configurations = context.configurations - self.placeholder = context.placeholder - self.cancelOnDisappear = context.cancelOnDisappear - } - /// Declares the content and behavior of this view. @ViewBuilder var body: some View { @@ -88,7 +82,7 @@ struct KFImageRenderer : View where HoldingView: KFImageHoldingView } } -@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) +@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) { @@ -101,7 +95,7 @@ extension Image { } #if canImport(UIKit) -@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) +@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *) extension UIImage.Orientation { func toSwiftUI() -> Image.Orientation { switch self {