I am trying to implement a functionality that requires a delegate method (like NSUserActivity
). Therefore I need a UIViewController
that conforms to NSUserActivityDelegate
(or similar other delegates), handles and hold all the required information. My problem is that I am using SwiftUI for my interface and therefore I am not using UIViewControllers
. So how can I implement this functionality and still use SwiftUI for the UI. What I tried: view1 is just a normal SwiftUI View
that can present (via NavigationLink
) view2 which is the view where in want to implement this functionality. So I tried instead of linking view1 and view2, linking view1 to a UIViewControllerRepresentable
which then handles the implementation of this functionality and adds UIHostingController(rootView: view2)
as a child view controller.
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)
}
}
I am having trouble with transferring the data between my VC and my view2. So I'm wondering if there is a better way to implement such a functionality within a SwiftUI View.
SwiftUI
app - and it sounds like it is - then you must useUIViewControllerRepresentable
. Without it? You cannot implement delegate methods. Now, you may be confused -UIHostingController
is how you do the reverse... add a SwiftUI view to yourUIKit
project. Here (and elsewhere, including WWDC videos) there are pretty decent examples of using a UIViewController in a SwiftUI project. My suggestion is to (1) get something working in aUIKit project first, then (2) expose it in a SwiftUI app - remember, a UIViewcontrollerRepresentable is just a SwiftUI
View`. – AndironUIViewControllerRepresentable
in order to add anUIViewController
to my app that can handle my delegate. Since I want to do my UI in SwiftUI thisUIViewController
attaches a child vc (see code) which is aUIHostingController
in order to present the UI in a SwiftUI View. My problem is that I can not really pass information between myUIViewController
(delegate handler) and my SwiftUIView
(view2) – StoogeUIHostingController
is used only in aUIKit
app. It's how you bring a SwiftUIView
into UIKit. Basically, you use either aUIViewControllerRepresentable
(UIKit >> SwiftUI) or aUIHostingController
(SwiftUI >> UIKit. For more details, check out Session 231: Integrating SwiftUI. – AndironUIViewControllerRepresentables
in my SwiftUI project. MTKView, UIImagePickerController, and UIActivityViewController. Two of them use delegates (the first two). I'm really not sure if they can help you, but I'm willing to try. The idea behind an image picker is to (a) present it, (b) use the delegate methods to either get the image picked or pass on that cancel was pressed, and (c) dismiss it. It's tied into my model - as of beta 5 it's now called anObservableObject
and update the various SwiftUI Views when the app state is updated. Can this help you? – Andiron