繁体   English   中英

转到 UIViewController 从 SwiftUI 查看

[英]Segue To UIViewController From SwiftUI View

我正在努力将一些 SwiftUI 内容实施到我现有的应用程序中。 我目前有一个 UIViewController,它托管一个用于相机预览的 MTKView。

我创建了一个新的 SwiftUI 视图,它现在是我的视图,在我的SceneDelegate.swift文件中设置。 正如预期的那样,SwiftUI 在启动时查看加载。 现在,我想创建一个 segue,当用户点击我的列表中的一行时,它将全屏显示到我现有的 UIViewController。这就是我的调用方式;

var body: some View {
    VStack {
        NavigationView {
            List(sessionTypes) { session in
                NavigationLink(destination: CameraControllerWrapper()) {
                    SessionRow(session: session)
                    .frame(height: 40.0)
                }
            }
        .navigationBarTitle(Text("Camera Types"))
        }
    }
}

对于后代,这是我的CameraControllerWrapper UIViewControllerRepresentable;

struct CameraControllerWrapper: UIViewControllerRepresentable {
typealias UIViewControllerType = CameraController

   func makeUIViewController(context: UIViewControllerRepresentableContext<CameraControllerWrapper>) -> CameraControllerWrapper.UIViewControllerType {
    return CameraController()
   }

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

虽然这“有效”,但只要调用 CameraController,我的应用程序就会崩溃,因为似乎无法找到我的任何 IBOutlets。 CameraController是storyboard内置的UIViewController。

我设法解决了这个问题,意识到我需要从 Storyboard 实例化 UIViewController,而不是在代码中(因为我在 Storyboard 中构建了它的布局,以及一些编程元素)。 要使用上面的NavigationLink ,我需要像这样调整我的UIViewControllerRepresentable

struct CameraControllerWrapper: UIViewControllerRepresentable {
    typealias UIViewControllerType = CameraController

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

    let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    let mainViewController: CameraController = mainStoryboard.instantiateViewController(withIdentifier: "CameraController") as! CameraController
      return mainViewController

    }

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

@ZbadhabitZ 回答的一些潜在优化,对于 Swift 可能相对较新的人,从一个简短的例子开始。

extension NotesVC : UIViewControllerRepresentable {

    func makeUIViewController(context: Context) -> NotesVC {
        let storyboard =  UIStoryboard(name: "Main", bundle: nil)
        let vc = storyboard.instantiateViewController(withIdentifier: "NotesVC") 
        return vc as! NotesVC
    }

    func updateUIViewController(_ vc: NotesVC, context: Context) {
        // your stuff here
    }
}
  1. 考虑添加 Swift 协议作为扩展。 它可以更简洁、更灵活(包括能够通过在单独的文件中完全定义协议扩展来使 class 适应协议)。 例如,我最近尝试了一个第三方选项卡 controller,它需要将我的 class 调整为一个协议,并且说明需要编辑几个添加的文件和我自己的文件,我能够将其中 80% 的文件作为扩展名放入一个单独的文件中,并且没有在试验新东西时不必弄乱我的代码,并且在我完成后很容易将其删除。

  1. Function arguments 重打字太过分了; 或至少令人困惑。

    Apple Developer demo展示了一个带有 PageViewController 的示例,显示所有额外的输入都是不必要的:


  1. 原始答案的代码没有使用 Swift 隐含类型。 例如,而

     let flag: Bool = false

    write:写:

     let flag = false

    flag将在该声明中隐式类型为Bool 那是因为false总是意味着Bool 正如默认情况下1.0始终表示Double一样,依此类推。 当您开始使用更长的 class 名称时,收益会更大。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM