Consider a UIVIewController where a custom back button needs to be set. The reason is that the user should be presented a confirmation dialog before navigating back where they can cancel the navigation, in case the back button was tapped accidentally. If the user confirms, a method in the UIVIewController should be executed.
The UIVIewController is wrapped in a UIViewControllerRepresentable. In a UIKit environment, the UIVIewController could just replace the back button like so:
let button = UIButton(type: .system)
navigationItem.leftBarButtonItem = UIBarButtonItem(customView: button)
However, since the view controller is presented in a SwiftUI NavigationView via a UIViewControllerRepresentable, I tried to set it for the parent view controller:
parent?.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: button)
This doesn't work. In fact, it results in 2 back buttons, the original one to the left and the custom added one to the right:
Even if UIViewControllerRepresentable.navigationBarItems(leading:) is set instead, then a second button is added to to the original back button.
How can the UIVIewController set the custom back button?

In the presenting view, hide the
UIViewControllerRepresentable's navigation bar back button. One would think that this only removes the back button, but if there is no other navigation item, the whole navigation bar is removed. To avoid this, also add an emptyTextview:This removes the
NavigationView's back button, leaving only the custom added button. But now, the view controller cannot be dismissed programmatically anymore with:So in the
UIViewControllerRepresentablethepresentationModeis passed to theUIViewController:Then in the
UIViewController, when the back button is tapped, the view is dismissed with:It works, but I'm sure there's a more elegant solution out there.