Reputation: 730
I have a SwiftUI inside a HostingViewController and a UIKit Viewcontroller. My goal is to switch between them with a button press. The problem is I cannot achieve to go from my SwiftUI View inside the HostingViewController back to UIKit.
I can go to the HostingViewController over my UIKit ViewController with this segue function:
@IBSegueAction func swiftUIAction(_ coder: NSCoder) -> UIViewController? {
return UIHostingController(coder: coder, rootView: WorkoutSelectView())
}
What I have tried
But I do not know how to go back. I have used a solution where I call a function from my AppDelegate of my SwiftUI View here:
guard let appDelegate: AppDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
appDelegate.switchBack()
and inside the Appdelegate I have this function:
func switchBack(){
guard var rootViewController = (UIApplication.shared.connectedScenes.first?.delegate as? SceneDelegate)?.window?.rootViewController else {
return
}
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "Home") as! HomeViewController
rootViewController.present(controller, animated: true, completion: { () -> Void in
})
}
The cool thing about this it works but the problem is then:
<WorkoutTracker.HomeViewController: 0x148f072a0>) whose view is not in the window hierarchy.
So have you got any ideas ?
Upvotes: 2
Views: 1720
Reputation: 258611
The possible approach is to pass completion callback into your SwiftUI view, like in below simplified demo
struct WorkoutSelectView: View {
var completion: () -> () = {}
var body: some View {
Button("Close", action: completion)
}
}
and use this callback in your UIViewController to dismiss presented controller, like
@IBSegueAction func swiftUIAction(_ coder: NSCoder) -> UIViewController? {
let controller = UIHostingController(coder: coder,
rootView: WorkoutSelectView() { [weak self] in
self?.dismiss(true)
})
return controller
}
Upvotes: 4