【问题标题】:How to pass value from class to struct in SwiftUI如何在 SwiftUI 中将值从类传递到结构
【发布时间】:2020-09-05 21:27:50
【问题描述】:

我上课了:

class ImagePickerCoordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate, ObservableObject{

    @Published var display = "Name"

    @Binding var image: UIImage?
    @Binding var isShown: Bool

    init(image: Binding<UIImage?>, isShown: Binding<Bool>){
        _image = image
        _isShown = isShown
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {

        if let uiImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {

            guard let convertedCIImage = CIImage(image: uiImage) else {
                fatalError("Cannot convert UIImage to CIIMage.")
            }

            detectFlower(image: convertedCIImage) { (flowerString, error) in

                self.display = flowerString!

            }

            image = uiImage
            isShown = false
        }
    }

    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        isShown = false
    }

    func detectFlower(image: CIImage,completion: @escaping (_ getString:String?,_ error:Error?)-> Void)  {
     guard let model = try? VNCoreMLModel(for: FlowerModels().model) else {

         fatalError("Cannot import a model.")
     }

     let request = VNCoreMLRequest(model: model) { (request, error) in

         let classification = request.results?.first as? VNClassificationObservation

        let nameOfFlower = String(classification?.identifier ?? "Unexpected type")

         completion(nameOfFlower,nil)

     }

     let handler = VNImageRequestHandler(ciImage: image)

     do {
         try handler.perform([request])
     } catch {
         print(error)
           completion(nil,error)
     }
    }
}

struct ImagePicker: UIViewControllerRepresentable {

    typealias UIViewControllerType = UIImagePickerController
    typealias Coordinator = ImagePickerCoordinator

    @Binding var image: UIImage?
    @Binding var isShown: Bool
    var sourceType: UIImagePickerController.SourceType = .camera

    func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {
    }

    func makeCoordinator() ->ImagePicker.Coordinator {
        return ImagePickerCoordinator(image: $image, isShown: $isShown)
    }

    func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {

        let picker = UIImagePickerController()
        picker.sourceType = sourceType
        picker.delegate = context.coordinator

        return picker
    }

}

我在其中初始化了@Published var display,它接收函数 imagePickerController 中的 detectFlower() 函数的结果。在结构 ScanWithCamera 中,我想使用此值在 Text() 中设置文本。我在 struct @EnvironmentObject var env: ImagePickerCoordinator 中初始化并设置了 Text(env.display),但我得到一个致命错误:没有找到 ImagePickerCoordinator 类型的 ObservableObject。 ImagePickerCoordinator 的 View.environmentObject(_:) 作为该视图的祖先可能会丢失。

struct ScanWithCamera: View {

    @State private var showSheet: Bool = false
    @State private var showImagePicker: Bool = false
    @State private var sourceType: UIImagePickerController.SourceType = .camera

    @State private var userImage: UIImage?
    @EnvironmentObject var env: ImagePickerCoordinator

    var body: some View {

        NavigationView{
            VStack{
                Text(env.display)
                    .foregroundColor(.blue)
                    .font(.system(size: 25))

                Image(uiImage: userImage ?? UIImage(named: "flower_logo")!)
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 400, height: 400)

            }
            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .top)

        }
        .navigationBarTitle(Text(""), displayMode: .inline)
        .navigationBarItems(trailing:
                HStack {
                    Button("Camera") {
                        self.showImagePicker = true
                        self.sourceType = .photoLibrary
                        print("Camera tapped!")
                    }
                }
        )
        .sheet(isPresented: $showImagePicker) {
            ImagePicker(image: self.$userImage, isShown: self.$showImagePicker, sourceType: self.sourceType).environmentObject(self.env)
        }
    }
}

如何将此文本从类函数传递到结构?

【问题讨论】:

    标签: swift binding swiftui swiftui-environment


    【解决方案1】:

    添加您的 SceneDelegate

    let env = ImagePickerCoordinator()
    

    并添加到您的 rootViewController:

    window.rootViewController = UIHostingController(rootView: contentView.environmentObject(env))
    

    现在您的 ImagePickerCoordinator 已连接到您的环境。

    并且不要在您的班级中使用@Binding

    在您的班级中也使用@Published 表示“image”和“isShown”。 然后,您可以通过env.image 访问所有这些变量,例如在您的 ScanWithCamera-View 中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-19
      • 2011-07-05
      • 1970-01-01
      • 2020-10-17
      • 1970-01-01
      • 1970-01-01
      • 2015-11-14
      相关资源
      最近更新 更多