簡體   English   中英

在 SwiftUI 視圖中實現委托

[英]Implement delegates within SwiftUI Views

我正在嘗試實現一個需要委托方法的功能(如NSUserActivity )。 因此,我需要一個符合NSUserActivityDelegate (或類似的其他委托)的UIViewController ,處理並保存所有必需的信息。 我的問題是我的界面使用 SwiftUI,因此我沒有使用UIViewControllers 那么我怎樣才能實現這個功能並且仍然使用 SwiftUI 作為 UI。 我嘗試過的: view1 只是一個普通的 SwiftUI View ,它可以(通過NavigationLink )呈現 view2,這是要實現此功能的視圖。 因此,我嘗試將 view1 鏈接到UIViewControllerRepresentable而不是鏈接 view1 和 view2,后者然后處理此功能的實現並將UIHostingController(rootView: view2)為子視圖控制器。

struct view1: View {    
    var body: some View {
        NavigationLink(destination: VCRepresentable()) {
            Text("Some Label")
        }
    }
}

struct view2: View {    
    var body: some View {
        Text("Hello World!")
    }
}

struct VCRepresentable: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> UIViewController {
        return implementationVC()
    }

    func updateUIViewController(_ uiViewController: UIViewController, context: Context) { }
}

class implementationVC: UIViewController, SomeDelegate for functionality {
    // does implementation stuff in delegate methods
    ...

    override func viewDidLoad() {
        super.viewDidLoad()

        attachChild(UIHostingController(rootView: view2()))
    }

    private func attachChild(_ viewController: UIViewController) {
        addChild(viewController)

        if let subview = viewController.view {
            subview.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview(subview)

            subview.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
            subview.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
            subview.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
            subview.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        }

        viewController.didMove(toParent: self)
    }
}

我在 VC 和 view2 之間傳輸數據時遇到問題。 所以我想知道是否有更好的方法在 SwiftUI 視圖中實現這樣的功能。

您需要創建一個符合UIViewControllerRepresentable的視圖,並有一個處理所有委托功能的Coordinator

例如,使用您的示例視圖控制器和委托:

struct SomeDelegateObserver: UIViewControllerRepresentable {
    let vc = SomeViewController()
    var foo: (Data) -> Void
    func makeUIViewController(context: Context) -> SomeViewController {
        return vc
    }

    func updateUIViewController(_ uiViewController: SomeViewController, context: Context) { }
    func makeCoordinator() -> Coordinator {
        Coordinator(vc: vc, foo: foo)
    }

    class Coordinator: NSObject, SomeDelegate {
        var foo: (Data) -> Void
        init(vc: SomeViewController, foo: @escaping (Data) -> Void) {
            self.foo = foo
            super.init()
            vc.delegate = self
        }
        func someDelegateFunction(data: Data) {
            foo(data)
        }
    }
}

用法:

struct ContentView: View {
    var dataModel: DataModel

    var body: some View {
        NavigationLink(destination: CustomView(numberFromPreviousView: 10)) {
            Text("Go to VCRepresentable")
        }
    }
}

struct CustomView: View {
    @State var instanceData1: String = ""
    @State var instanceData2: Data?
    var numberFromPreviousView: Int // example of data passed from the previous view to this view, the one that can react to the delegate's functions
    var body: some View {
        ZStack {
            SomeDelegateObserver { data in
                print("Some delegate function was executed.")
                self.instanceData1 = "Executed!"
                self.instanceData2 = data
            }
            VStack {
                Text("This is the UI")
                Text("That, in UIKit, you would have in the UIViewController")
                Text("That conforms to whatever delegate")
                Text("SomeDelegateObserver is observing.")
                Spacer()
                Text(instanceData1)
            }
        }
    }
}

注意:我將VCRepresentable重命名為SomeDelegateObserver以更好地說明它的作用:它的唯一目的是等待委托函數執行,然后運行您提供的閉包(即本例中的foo )。 您可以使用此模式創建盡可能多的函數以“觀察”您關心的任何委托函數,然后執行可以更新 UI、數據模型等的代碼。在我的示例中,當SomeDelegate觸發someDelegateFunction(data:) ,視圖將顯示“已執行”並更新數據實例變量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM