Alright people, I think I got something.
After two days of constant struggling with all kinds of workarounds and after diving into private view hierarchies, this is what I concluded to:
Here's the view hierarchy of a UINavigationBar to its UIBarButtonItems:
UINavigationBar > _UINavigationBarContentView > _UIButtonBarStackView(s) > UIButton(s)
By independently looking at each one of the views and their auto layout constraints (not by the way visible in the Debug View Hierarchy!), I could see that there are constraints to the layout guide, and that was the cause of the weird horizontal positioning of the UIBarButtonItems.
In particular the content view's layout margins were the following (output from the console):
(lldb) po self.navigationController?.navigationBar.subviews[2].layoutMargins
▿ Optional<UIEdgeInsets>
▿ some : UIEdgeInsets
- top : 0.0
- left : 16.0
- bottom : 0.0
- right : 16.0
What I found is that simply setting the layout margins of the content view would fix the issue. You can do this easily in the layoutSubviews() method of your custom UINavigationBar. Since accessing the private view directly wouldn't be safe, iterating through all its subviews does the trick.
override func layoutSubviews() {
super.layoutSubviews()
for view in subviews {
view.layoutMargins = .zero
}
}
Not the cleanest solution but I guess will do until Apple addresses the issue.