Last active
December 30, 2020 01:12
-
-
Save StarLard/fb1e02f4dc616aee02970453847c1c2e to your computer and use it in GitHub Desktop.
FetchImageView
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SwiftUI | |
import Nuke | |
@available(watchOS 7.0, *) | |
@available(tvOS 14.0, *) | |
@available(iOS 14.0, *) | |
@available(OSX 11.0, *) | |
public struct FetchImageView<Placeholder>: View where Placeholder: View { | |
public var body: some View { | |
content | |
.onAppear { | |
if let request = self.request { | |
// Restarts the request if previous download failed | |
fetchImage.fetch(request: request, lowDataRequest: lowDataRequest) | |
} else { | |
fetchImage.reset() | |
} | |
fetchImage.priority = .normal | |
} | |
.onDisappear { | |
fetchImage.priority = .low | |
} | |
} | |
/// Initializes the fetch request and immediately start loading. | |
public init(request: ImageRequest? = nil, lowDataRequest: ImageRequest? = nil, @ViewBuilder placeholder: () -> Placeholder) { | |
self.placeholder = placeholder() | |
self.request = request | |
self.lowDataRequest = lowDataRequest | |
} | |
/// Initializes the fetch request and immediately start loading. | |
public init(url: URL, @ViewBuilder placeholder: () -> Placeholder) { | |
self.init(request: ImageRequest(url: url), placeholder: placeholder) | |
} | |
/// A convenience initializer that fetches the image with a regular URL with | |
/// constrained network access disabled, and if the download fails because of | |
/// the constrained network access, uses a low data URL instead. | |
public init(regularUrl: URL, lowDataUrl: URL, @ViewBuilder placeholder: () -> Placeholder) { | |
var request = URLRequest(url: regularUrl) | |
request.allowsConstrainedNetworkAccess = false | |
self.init(request: ImageRequest(urlRequest: request), lowDataRequest: ImageRequest(url: lowDataUrl), placeholder: placeholder) | |
} | |
@StateObject | |
private var fetchImage = FetchImage() | |
private var request: ImageRequest? | |
private var lowDataRequest: ImageRequest? | |
private var placeholder: Placeholder | |
@ViewBuilder | |
private var content: some View { | |
if let fetchedImage = fetchImage.image { | |
#if os(macOS) | |
Image(nsImage: fetchedImage) | |
#else | |
Image(uiImage: fetchedImage) | |
#endif | |
} else { | |
placeholder | |
} | |
} | |
} | |
@available(watchOS 7.0, *) | |
@available(tvOS 14.0, *) | |
@available(iOS 14.0, *) | |
@available(OSX 11.0, *) | |
public extension FetchImageView where Placeholder == Color { | |
/// Initializes the fetch request and immediately start loading. | |
init(request: ImageRequest? = nil, lowDataRequest: ImageRequest? = nil) { | |
self.init(request: request, lowDataRequest: lowDataRequest) { | |
Color.white | |
} | |
} | |
/// Initializes the fetch request and immediately start loading. | |
init(url: URL) { | |
self.init(url: url) { | |
Color.white | |
} | |
} | |
/// A convenience initializer that fetches the image with a regular URL with | |
/// constrained network access disabled, and if the download fails because of | |
/// the constrained network access, uses a low data URL instead. | |
init(regularUrl: URL, lowDataUrl: URL) { | |
self.init(regularUrl: regularUrl, lowDataUrl: lowDataUrl) { | |
Color.white | |
} | |
} | |
} | |
#if DEBUG | |
@available(watchOS 7.0, *) | |
@available(tvOS 14.0, *) | |
@available(iOS 14.0, *) | |
@available(OSX 11.0, *) | |
struct FetchImageView_Previews: PreviewProvider { | |
static var previews: some View { | |
FetchImageView(url: URL(string: "https://cloud.githubusercontent.com/assets/1567433/13918338/f8670eea-ef7f-11e5-814d-f15bdfd6b2c0.png")!) { | |
Text("Loading...") | |
} | |
} | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment