Skip to content

Commit

Permalink
Merge pull request onevcat#1707 from onevcat/feature/StateObject
Browse files Browse the repository at this point in the history
`@StateObject`  based image binder
  • Loading branch information
onevcat authored Jun 12, 2021
2 parents a00becf + f38010d commit e724dde
Show file tree
Hide file tree
Showing 15 changed files with 106 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import SwiftUI
import Kingfisher

@available(iOS 13.0, *)
@available(iOS 14.0, *)
struct AnimatedImageDemo: View {

@State private var index = 1
Expand Down Expand Up @@ -66,7 +66,7 @@ struct AnimatedImageDemo: View {

}

@available(iOS 13.0, *)
@available(iOS 14.0, *)
struct AnimatedImageDemo_Previews: PreviewProvider {

static var previews: some View {
Expand Down
51 changes: 51 additions & 0 deletions Demo/Demo/Kingfisher-Demo/SwiftUIViews/GeometryReaderDemo.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//
// GeometryReaderDemo.swift
// Kingfisher
//
// Created by JP20028 on 2021/06/12.
//
// Copyright (c) 2021 Wei Wang <[email protected]>
//
// 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()
}
}
6 changes: 3 additions & 3 deletions Demo/Demo/Kingfisher-Demo/SwiftUIViews/ListDemo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import Kingfisher
import SwiftUI

@available(iOS 13.0, *)
@available(iOS 14.0, *)
struct ListDemo : View {

let index = 1 ..< 700
Expand All @@ -40,7 +40,7 @@ struct ListDemo : View {
}
}

@available(iOS 13.0, *)
@available(iOS 14.0, *)
struct ImageCell: View {

@State var done = false
Expand Down Expand Up @@ -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()
Expand Down
11 changes: 5 additions & 6 deletions Demo/Demo/Kingfisher-Demo/SwiftUIViews/MainView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import SwiftUI
import Kingfisher

@available(iOS 13.0, *)
@available(iOS 14.0, *)
struct MainView: View {
var body: some View {
List {
Expand All @@ -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()
Expand Down
4 changes: 2 additions & 2 deletions Demo/Demo/Kingfisher-Demo/SwiftUIViews/SingleViewDemo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import Kingfisher
import SwiftUI

@available(iOS 13.0, *)
@available(iOS 14.0, *)
struct SingleViewDemo : View {

@State private var index = 1
Expand Down Expand Up @@ -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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import SwiftUI
import UIKit

@available(iOS 13.0, *)
@available(iOS 14.0, *)
class SwiftUIViewController: UIHostingController<MainView> {
required init?(coder: NSCoder) {
super.init(coder: coder, rootView: MainView())
Expand Down
4 changes: 4 additions & 0 deletions Demo/Kingfisher-Demo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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 */; };
Expand Down Expand Up @@ -158,6 +159,7 @@
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>"; };
4B779C8426743C2800FF9C1E /* GeometryReaderDemo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeometryReaderDemo.swift; sourceTree = "<group>"; };
4B92FE5525FF906B00473088 /* AutoSizingTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoSizingTableViewController.swift; sourceTree = "<group>"; };
4BCCF3361D5B02F8003387C2 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
4BCCF3371D5B02F8003387C2 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
Expand Down Expand Up @@ -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 */,
Expand Down Expand Up @@ -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 */,
Expand Down
5 changes: 3 additions & 2 deletions Sources/SwiftUI/ImageBinder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
5 changes: 3 additions & 2 deletions Sources/SwiftUI/ImageContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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<HoldingView: KFImageHoldingView> {
var binder: ImageBinder
Expand All @@ -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
Expand Down
7 changes: 4 additions & 3 deletions Sources/SwiftUI/KFAnimatedImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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<HoldingView>
Expand All @@ -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)
Expand All @@ -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 {
Expand Down
33 changes: 7 additions & 26 deletions Sources/SwiftUI/KFImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,44 +26,25 @@

#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<Image>
public init(context: Context<Image>) {
self.context = 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 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(
Expand All @@ -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.
Expand Down Expand Up @@ -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 {
Expand Down
5 changes: 3 additions & 2 deletions Sources/SwiftUI/KFImageOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down Expand Up @@ -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.
Expand Down
Loading

0 comments on commit e724dde

Please sign in to comment.