SwitUI-实现URL图片显示

实现方法一(纯使用SwiftUI)

import SwiftUI

struct WebImage: View {
    @ObservedObject var imageLoader: ImageLoader
    @State var image: UIImage = UIImage()

    init(withURL url: String) {
        imageLoader = ImageLoader(urlString:url)
    }

    var body: some View {
        VStack {
            //在这里,我们可以直接检查imageLoader的data属性。如果为零,则使用空的UIImage,否则可以使用数据创建UIImage。设置完数据后,@ Published将通知ImageView,它将使用imageLoader中数据的更新版本重新加载Image。
            Image(uiImage: imageLoader.data != nil ? UIImage(data:imageLoader.data!)! : UIImage())
                .resizable()
                .aspectRatio(contentMode: .fit)
        }
    }
}

class ImageLoader: ObservableObject {
    //通过使用@Published属性包装器,我们不需要像PassthroughSubject那样创建自己的发布者并通知我们的订阅者。属性包装器会处理它。
    @Published var data:Data?
    
    init(urlString: String) {
        guard let url = URL(string: urlString) else { return }
        let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
            guard let data = data else { return }
            DispatchQueue.main.async { self.data = data }
        }
        task.resume()
    }
}

#if DEBUG
struct WebImage_Previews: PreviewProvider {
    static var previews: some View {
        WebImage(withURL: "https://dss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1158873959,778733211&fm=26&gp=0.jpg")
    }
}
#endif

实现方法二(纯使用SwiftUI和Combine)

import SwiftUI
import Combine

struct WebImage: View {
    @ObservedObject var imageLoader: ImageLoader
    @State var image: UIImage = UIImage()

    init(withURL url: String) {
        imageLoader = ImageLoader(urlString:url)
    }

    var body: some View {
        VStack {
            Image(uiImage: image)
                .resizable()
                .aspectRatio(contentMode: .fit)
        }.onReceive(imageLoader.didChange) { data in
            self.image = UIImage(data: data) ?? UIImage()
        }
    }
}

class ImageLoader: ObservableObject {
    var didChange = PassthroughSubject<Data, Never>()
    var data = Data() {
        didSet {
            didChange.send(data)
        }
    }
    
    init(urlString: String) {
        guard let url = URL(string: urlString) else { return }
        let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
            guard let data = data else { return }
            DispatchQueue.main.async { self.data = data }
        }
        task.resume()
    }
}

#if DEBUG
struct WebImage_Previews: PreviewProvider {
    static var previews: some View {
        WebImage(withURL: "https://dss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1158873959,778733211&fm=26&gp=0.jpg")
    }
}
#endif

最终效果:


截屏2019-12-0714.19.47.png
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 开始之前:请确保你的系统版本为macOS 10.15及以上版本且已经安装了Xcode 11。这种组合使您可以在Xc...
    Augs阅读 3,015评论 0 7
  • 原文作者:ZacJj原文地址:https://juejin.im/post/5d05b45bf265da1bcc1...
    _小迷糊_997阅读 4,939评论 1 14
  • 本文的主角[SwiftUI-CSS](https://github.com/hite/SwiftUI-CSS) 是...
    hite和落雁阅读 2,831评论 0 2
  • 我要成为学习型社群运营行家 【今日行家行动】 01.冥想+跑步 02.建立工作销项表 03.工作事务处理 04.阅...
    大侠123阅读 172评论 0 0
  • 【分享人】:周小蓉 【成果】:235的海报生成! 【体验】:爽!爽!爽! 助教第二天,昨晚三点多才睡,早上六点起床...
    与蓉有约阅读 232评论 0 0