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