I want to return to the previous view via a UIViewController button in a UIViewControllerRepresentable.
When I click on uiButtonBack, nothing happens.
What is wrong in my code?
MainContent:
struct ContentView: View {
var body: some View {
NavigationView {
VStack {
NavigationLink(destination: MyUIKitView()) { Text("Go to UIKit View") }
}
.navigationTitle("Main View")
}
}
}
UIViewControllerRepresentable:
struct MyUIKitView: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> MyUiViewController {
let viewController = MyUiViewController()
return viewController
}
func updateUIViewController(_ uiViewController: MyUiViewController, context: Context) { }
}
UIViewController:
class MyUiViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
mainView.uiButtonBack.addTarget(self,
action: #selector(back),
for: .touchUpInside)
mainView.uiButtonBack.setTitle("Back", for: .normal)
}
@objc func back() {
self.navigationController?.popToRootViewController(animated: true)
}
}
Thanks to help me.
By inspecting the view controller hierarchy, it seems like SwiftUI wraps the content of the
NavigationViewinto some sort split view controller by default.If you set the style of the
NavigationViewto.stack, your code works correctly.If you don't need to support versions before iOS 16, you should use
NavigationStackinstead, which also makespopToRootViewControllerwork correctly.That said, using
popToRootViewControllerdepends on the fact that SwiftUI wraps your UIKit view controller in aUINavigationController, which might change in the future. IMO, it is better to just pass thedismissaction from the SwiftUI side to the UIKit side: