On UINavigationBar the leftBarButtonItem and rightBarButtonItem of the UINavigationItem are placed incorrectly on iOS 16

When I build an app with Xcode 14.0.1, then on iOS 16 the leftBarButtonItem is placed too far to the left and the rightBarButtonItem is placed way too far to the right on the UINavigationBar. But with the same build it still looks fine on iOS 15.5 and below.

Does anyone have an idea how I can get everything on the UINavigationBar to display properly on iOS 16?

I have already tried all three styles of UINavigationItemStyle that are available since iOS 16. No success. With all 3 styles it looks like on the picture.

It's about the "Cancel" and "Done" buttons, which you can see in the image:

Answered by vsmedia in 730770022

An important line of code was missing. After I added this line, everything is displayed correctly with iOS 16 as well.

[self addChildViewController:secondViewController];

I have now made an empty test project where I do nothing else than add the two UIBarButtonItems to the UINavigationBar in the source code and it is displayed correctly under iOS 16. So the problem is not with the iOS 16 but with my source code in a specific project. It's just weird that it shows up correctly on iOS 15.5. Unfortunately I haven't found the cause of the wrong placement of the buttons in my project yet.

Unfortunately, the two buttons of UIBarButtonItem are also placed incorrectly in the empty test project under iOS 16 if I do everything as in the real project. I add the view of a second UIViewController to the main view and then create the UINavigationBar on top of the second UIViewController's view. It worked fine until iOS 15.5. Unfortunately not with iOS 16. Does anyone know how I can fix the problem?


    UIEdgeInsets safeAreaInsets = self.view.superview.safeAreaInsets;

    secondViewController.view.frame = CGRectMake(safeAreaInsets.left, 
                                                 safeAreaInsets.top, 
                                                 self.view.frame.size.width - safeAreaInsets.left - safeAreaInsets.right, 
                                                 self.view.frame.size.height - safeAreaInsets.top - safeAreaInsets.bottom);

    secondViewController.view.backgroundColor = [UIColor darkGrayColor];

    [self.view addSubview:secondViewController.view];

    UINavigationBar *navigationBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, secondViewController.view.frame.size.width, 44)];

    [secondViewController.view addSubview:navigationBar];

    UINavigationItem *navigationItem  = [[UINavigationItem alloc] init];
    navigationItem.leftBarButtonItem  = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:nil];
    navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone   target:self action:nil];

    [navigationBar pushNavigationItem:navigationItem animated:NO];

With the code below it looks good even with iOS 16, but I really need the first method as in the code above.


    UIEdgeInsets safeAreaInsets = self.view.superview.safeAreaInsets;

    secondViewController.view.backgroundColor = [UIColor whiteColor];

    UINavigationBar *navigationBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, safeAreaInsets.top, 
                                                                                       secondViewController.view.frame.size.width, 44)];

    [secondViewController.view addSubview:navigationBar];

    UINavigationItem *navigationItem  = [[UINavigationItem alloc] init];
    navigationItem.leftBarButtonItem  = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:nil];
    navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone   target:self action:nil];

    [navigationBar pushNavigationItem:navigationItem animated:NO];

    secondViewController.modalPresentationStyle = UIModalPresentationFullScreen;

    [self presentViewController:secondViewController animated:NO completion:nil];

Accepted Answer

An important line of code was missing. After I added this line, everything is displayed correctly with iOS 16 as well.

[self addChildViewController:secondViewController];

Of course, it would be nice where you added that new line of code which solved the issue, in the context of your original code.

On UINavigationBar the leftBarButtonItem and rightBarButtonItem of the UINavigationItem are placed incorrectly on iOS 16
 
 
Q