【问题标题】:Navigate to UIViewController from SwiftUI从 SwiftUI 导航到 UIViewController
【发布时间】:2020-06-19 16:10:10
【问题描述】:

我的初始视图是使用 SwiftUI 构建的。

我想从这个转换到 UIViewController 并调用一个可能会改变设计的方法,一个例子是隐藏一个 IBOutlet。

这是我目前正在做的事情:

@available(iOS 13.0, *)
struct DetailViewControllerWrapper: UIViewControllerRepresentable {
    typealias UIViewControllerType = DetailViewController

    func makeUIViewController(context: UIViewControllerRepresentableContext<DetailViewControllerWrapper>) -> DetailViewControllerWrapper.UIViewControllerType {

        let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let detailViewController: DetailViewController = mainStoryboard.instantiateViewController(withIdentifier: "detailViewController") as! DetailViewController
        detailViewController.someMethod()
        return detailViewController
    }

    func updateUIViewController(_ uiViewController: DetailViewControllerWrapper.UIViewControllerType, context: UIViewControllerRepresentableContext<DetailViewControllerWrapper>) {
        //
    }
}

这正在推送到我的 DetailViewController,但我收到了 Unexpectedly found nil while implicitly unwrapping an Optional value 错误。

关于从 SwiftUI 导航到 UIKit / UIViewController 有什么建议吗?

【问题讨论】:

  • 我猜detailViewController.someMethod() 使用IBOutlet 属性?崩溃断点指向该属性的使用?我认为在实例化视图控制器之后还没有直接设置出口。
  • 如果你看到DetailViewController的视图然后崩溃,那么它是在DetailViewController的实现中,而不是在提供的代码中。
  • 我已经取得了一些进展,但我遇到的一件事是我的状态栏最初是隐藏的,但是当从我的 SwiftUI 视图导航到我的 UIIVewController 时,它变得不隐藏,即使正在调用 prefersStatusBarHidden。有什么想法吗?

标签: ios swift xcode uikit swiftui


【解决方案1】:

使用UIViewRepresentable 的一部分是调用一个称为makeCoordinator() 的必需函数,如文档中引用的here。 Apple 还有一个关于如何与 UIKit 交互的教程,你可以找到 here。 Paul Hudson here 的另一个教程也可能对您有用。我使用其中的协调器模式在我正在开发的 SwiftUI 应用程序中提供UIImagePickerController。该代码如下。您会注意到为UIImagePickerController 提供我需要的功能的嵌套类,在您的情况下,我相信您只需要调用DetailViewController。我希望这有帮助。 -丹

import SwiftUI

class PhotosData: NSObject, Codable {
    var image: String?

    init(image: String) {
        self.image = image
      }
    }

struct ImagePicker: UIViewControllerRepresentable {
    @Environment(\.presentationMode) var presentationMode
    @Binding var image: UIImage?

class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
    let parent: ImagePicker

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        if let uiImage = info[.originalImage] as? UIImage {
            parent.image = uiImage
        }
        parent.presentationMode.wrappedValue.dismiss()
    }

    init(_ parent: ImagePicker) {
        self.parent = parent
        }
    }

    func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
        let picker = UIImagePickerController()
        picker.delegate = context.coordinator
        return picker
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) { 
    /*Required. Not used*/ 
        }

}

【讨论】:

  • 我设置了我的协调器,但我的插座上仍然收到相同的消息。虽然,我没有设置 context.coordinator 。我不完全确定如何仅在 ViewController 上执行此操作,因为我没有使用 ImagePicker 或类似的东西。
  • 从上面划掉。我现在可以导航并调用正确的方法。不过,我看到的几件事,当导航完成时,我的状态栏开始为隐藏状态变得可见。此外,导航回 SwiftUI 视图的最佳方式是什么?使用 popToViewController 有效,但后来我卡在 SwiftUI 上,无法返回。
  • 如果在 SwiftUI 视图中状态栏变得可见,请尝试将修饰符 .statusBar(hidden: true) 添加到视图中。不幸的是,我不确定你问题的第二部分。您可以发布导航代码吗?
猜你喜欢
  • 2021-04-06
  • 2020-06-03
  • 2021-05-25
  • 2012-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多