URL中的SwiftUI图像未显示

URL中的SwiftUI图像未显示,swift,swiftui,Swift,Swiftui,当我想显示来自URL的图像时,我遇到了一个问题。我创建了一个用于下载数据并向前发布数据的类-ImageLoader: class ImageLoader: ObservableObject { var didChange = PassthroughSubject<Data, Never>() var data = Data() { didSet { didChange.send(data) } }

当我想显示来自URL的图像时,我遇到了一个问题。我创建了一个用于下载数据并向前发布数据的类-
ImageLoader

class ImageLoader: ObservableObject {
    var didChange = PassthroughSubject<Data, Never>()
    var data = Data() {
        didSet {
            didChange.send(data)
        }
    }
    
    func loadData(from urlString: String?) {
        if let urlString = urlString {
            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()
        }
    }
}
我的问题是,如果我只是运行我的项目,图像不会更改,默认情况下只显示
图像UIImage(名为:“homelessDogsCats”)

如果我在里面添加一个断点

onAppear { 
    self.imageLoader.loadData(from: urlString) 
}
只要向前一步,图像就会显示出来


我在另一个视图中也遇到了同样的问题,该视图通常不显示URL中的
图像,但有时会显示。

尝试使用
@Published
-这样您就不需要自定义
直通主题了。

class ImageLoader: ObservableObject {
    // var didChange = PassthroughSubject<Data, Never>() <- remove this
    @Published var data: Data?
    ...
}

注意:如果您使用的是SwiftUI 2,则可以使用
@StateObject
而不是
@ObservedObject
onChange
而不是
onReceive

struct ImageView: View {
    var urlString: String
    @StateObject var imageLoader = ImageLoader()
    @State var image = UIImage(named: "homelessDogsCats")!

    var body: some View {
        ZStack() {
            Image(uiImage: image)
                .resizable()
                .onChange(of: imageLoader.data) { data in
                    guard let data = data else { return }
                    self.image = UIImage(data: data) ?? UIImage()
                }
        }.onAppear {
            self.imageLoader.loadData(from: urlString)
        }
    }
}

再次感谢您的回复:D我认为这样做是不可能的。无法在以下位置打开数据:.onReceive(Just(imageLoader.$data)){guard let data=data else中的数据{return}self.image=UIImage(data:data)??UIImage()}条件绑定的初始值设定项必须具有可选类型,而不是“Published.Publisher”@AdrianMacarenco抱歉,我已修复了我的答案。但是您也可以尝试使用
onChange
修饰符。不,它不起作用。但我不理解,为什么它不工作…如果我使用断点然后继续运行项目,有什么区别。我的目标是iOS 13,它正在抱怨目标:(但很难理解为什么它不能正常工作,为什么如果我使用断点它会改变图像。为什么在iOS 13上这样做?@AdrianMacarenco是的,我修复了所有问题并测试了两个版本。请查看更新的答案。
struct ImageView: View {
    var urlString: String
    @ObservedObject var imageLoader = ImageLoader()
    @State var image = UIImage(named: "homelessDogsCats")!

    var body: some View {
        ZStack() {
            Image(uiImage: image)
                .resizable()
                .onReceive(imageLoader.$data) { data in
                    guard let data = data else { return }
                    self.image = UIImage(data: data) ?? UIImage()
                }
        }.onAppear {
            self.imageLoader.loadData(from: urlString)
        }
    }
}
struct ImageView: View {
    var urlString: String
    @StateObject var imageLoader = ImageLoader()
    @State var image = UIImage(named: "homelessDogsCats")!

    var body: some View {
        ZStack() {
            Image(uiImage: image)
                .resizable()
                .onChange(of: imageLoader.data) { data in
                    guard let data = data else { return }
                    self.image = UIImage(data: data) ?? UIImage()
                }
        }.onAppear {
            self.imageLoader.loadData(from: urlString)
        }
    }
}