ios - 如何从模型中的函数接收 View 中的异步结果?

标签 ios swift swiftui

我正在加载我的 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/

相关文章:

ios - 在 swiftui 中关闭 View

ios - 加速度计数据始终为负

iphone - 重新加载AQGridview

ios - 如何找到自动增长的 UILabel 的实际高度

ios - SwiftUI - 更改 KVKCalendar 的 CalendarType

image - 动画在 AnyTransition SwiftUI 上不起作用

ios - 在 iOS "monitor"NSUserDefaults 读取和写入

ios - 缩放图像以适合 - iOS

ios - Realm 模型在运行单元测试时不存储任何数据

swift - 生成对象时的 EXC_BAD_INSTRUCTION