簡體   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