我正在加载我的 Image
从一个网址:
EditProfile.swift
struct EditableCircleImage: View {
@ObservedObject var storage = Storages()
let key: String
let imgName: String?
@State var image: Image = Image(systemName: "plus.circle")
@State var uiImage: UIImage?
@State var showImagePicker = false
let uid = UserAuth().uid ?? "<uid>"
var body: some View {
ZStack {
image
.resizable()
.scaledToFit()
.frame(height: 200)
.clipShape(Circle())
.overlay(Circle().stroke(Color.orange, lineWidth: 2))
Button(action: { self.showImagePicker.toggle() }){
Image(systemName: "pencil.circle.fill")
.resizable()
.scaledToFit()
.frame(height: 40)
.foregroundColor(.gray)
}.offset(x: 40, y: 50)
.onAppear {
self.loadImageFromUrl(imgName: self.imgName)
}
}
}
func loadImageFromUrl(imgName: String?) {
guard let imgName = imgName else {
return
}
print("imgName: \(imgName)")
let url = URL(string: "http://app-8kui4.appspot.com.storage.googleapis.com/users/\(uid)/\(imgName)")!
URLSession.shared.dataTask(with: url){ data, response, err in
print("DATA: \(data) | ERR: \(err)")
if let data = data, let uiImage = UIImage(data: data) {
DispatchQueue.main.async {
self.image = Image(uiImage: uiImage)
}
}
}.resume()
}
}
我需要重复使用完全相同的功能 loadImageFromUrl()
在另一个 View 中。ProfileView.swift
struct CircleImage : View {
let imgURL: String?
@State var image: Image = Image(systemName: "plus.circle")
let uid = UserAuth().uid ?? "<uid>"
var body: some View {
image
.resizable()
.scaledToFit()
.frame(height: 200)
.clipShape(Circle())
.overlay(Circle().stroke(Color.orange, lineWidth: 2))
.onAppear {
// loadImageFromUrl()
}
}
}
我无法添加 loadImageFromUrl()
在模型中,因为它失去了对 Image
的引用在 View 中。我不想添加 @Published
模型中的属性并从那里引用图像,因为它不是动态和可扩展的 - 我只是想将引用传递给我的 CircleImage
struct 为 Model,然后更改 CircleImage
Image
.这可能吗?
最佳答案
您不能传递对 CircleImage
的引用因为不是引用类型,是值类型struct,是-a View
协议(protocol)。
如loadImageFromUrl
实际上并不依赖于任何 View ,将其放在顶层(为了可重用性)并在参数中添加回调:
func loadImageFromUrl(imgName: String?, completion: @escaping (UIImage)->()) {
guard let imgName = imgName else {
return
}
print("imgName: \(imgName)")
let url = URL(string: "http://app-8kui4.appspot.com.storage.googleapis.com/users/\(uid)/\(imgName)")!
URLSession.shared.dataTask(with: url){ data, response, err in
print("DATA: \(data) | ERR: \(err)")
if let data = data, let uiImage = UIImage(data: data) {
DispatchQueue.main.async {
completion(Image(uiImage: uiImage))
}
}
}.resume()
}
所以现在你可以在两个 View 中重复使用它(当然它假设 CircleImage
将有一些 imgName
属性).onAppear {
loadImageFromUrl(imgName: self.imgName) { self.image = $0 }
}
关于ios - 如何从模型中的函数接收 View 中的异步结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62549450/