Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import SwiftUI
- import Combine
- import class Kingfisher.KingfisherManager
- extension Image {
- func remoteImage(from imageURL:URL?) -> some View {
- ModifiedContent(content: self, modifier: RemoteImage(loader: ImageLoader(imageURL)))
- }
- }
- final class ImageLoader: ObservableObject {
- let imageURL: URL?
- @Published var image: UIImage? = nil
- var objectWillChange: AnyPublisher<UIImage?, Never> = Publishers.Sequence<[UIImage?], Never>(sequence: []).eraseToAnyPublisher()
- var cancellable: AnyCancellable?
- init(_ path: URL?) {
- self.imageURL = path
- self.objectWillChange = $image.handleEvents(receiveSubscription: { [weak self] sub in
- self?.fetchImage()
- }, receiveCancel: { [weak self] in
- self?.cancellable?.cancel()
- }).eraseToAnyPublisher()
- }
- private func fetchImage() {
- if image != nil { return }
- guard let imageUrl = imageURL else {
- print("error with: \(String(describing: imageURL))")
- return
- }
- KingfisherManager.shared.retrieveImage(with: imageUrl) { result in
- switch result {
- case .success(let value):
- self.image = value.image
- case .failure(let error):
- print(error)
- }
- }
- }
- }
- //MARK:- Remote image implementation
- struct RemoteImage: ViewModifier {
- @ObservedObject var loader: ImageLoader
- func body(content: Content) -> some View {
- // if loader.image != nil {
- // return Image(uiImage: loader.image!)
- // .resizable()
- // .eraseToAnyView()
- // } else {
- // return content.eraseToAnyView()
- // }
- ZStack {
- content
- .opacity( loader.image == nil ? 1 : 0)
- loader.image.map {
- Image(uiImage: $0)
- .resizable()
- .eraseToAnyView()
- }
- }
- }
- }
- extension View {
- func eraseToAnyView() -> AnyView {
- return AnyView(self)
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement