首页 > 解决方案 > 在 UIViewControllerRepresentable 中处理 @IBOutlet

问题描述

我正在尝试将 Apple 演示中的一个 ViewController 包装在 SwiftUI UIViewControllerRepresentable 中,它有一组连接到主情节提要的 IBOutlets。我该如何处理这种情况?应该将 IBOutlets 替换为 View 结构,还是应该尝试将 Storyboard 与 SwiftUI 合并?

struct ARViewContainer: UIViewControllerRepresentable {
    
    @ObservedObject var model: Model
    
    typealias UIViewControllerType = ARView
    
    func makeUIViewController(context: Context) -> ARView {
        return ARView(model)
    }
    func updateUIViewController(_ uiViewController:
        ARViewContainer.UIViewControllerType, context:
        UIViewControllerRepresentableContext<ARViewContainer>) { }
    
}

class ARView: UIViewController, ARSCNViewDelegate {
    
    @ObservedObject var model: Model
    
    // MARK: IBOutlets
    
    @IBOutlet var sceneView: VirtualObjectARView!
    
    @IBOutlet weak var addObjectButton: UIButton!
    
    @IBOutlet weak var blurView: UIVisualEffectView!
    
    @IBOutlet weak var spinner: UIActivityIndicatorView!
    
    @IBOutlet weak var upperControlsView: UIView!

标签: swiftuiuikit

解决方案


它绝对可以工作,但你必须UIViewController从情节提要中实例化你的。现在,您只是用 初始化它ARView(),因此它与情节提要无关,也无法连接插座。

基本示例:

struct ContentView : View {
    var body: some View {
        MyStoryboardVCRepresented()
    }
}

struct MyStoryboardVCRepresented : UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> MyStoryboardVC {
        UIStoryboard(name: "MyStoryboard", bundle: Bundle.main).instantiateViewController(identifier: "MyVC") as! MyStoryboardVC //theoretically unsafe to unwrap like this with `!`, but we know it works, since the view controller is included in the storyboard
    }
    
    func updateUIViewController(_ uiViewController: MyStoryboardVC, context: Context) {
        uiViewController.label.text = "Hello, world!"
    }
}

class MyStoryboardVC : UIViewController {
    @IBOutlet var label : UILabel!
}

推荐阅读