navigationBar setBackgroundImage not working on iOS15

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.navigationController.navigationBar setBackgroundImage:[self imageWithColor:[UIColor redColor]] forBarMetrics:UIBarMetricsDefault];
}

- (UIImage *)imageWithColor:(UIColor *)color {
    CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

it works on iOS14, but on iOS15. it doesn't work. the color of navigationBar does't change

Accepted Reply

As of iOS 15, UINavigationBar, UIToolbar, and UITabBar will use their scrollEdgeAppearance when your view controller's associated scroll view is at the appropriate edge (or always if you don't have a UIScrollView in your hierarchy, more on that below).

You must adopt the UIBarAppearance APIs (available since iOS 13, specializations for each bar type) to customize this behavior. UIToolbar and UITabBar add scrollEdgeAppearance properties for this purpose in iOS 15.

For your specific case, the customization code looks something like this:

UINavigationBarAppearance *app = [UINavigationBarAppearance new];
[app configureWithOpaqueAppearance];
app.backgroundColor = UIColor.redColor;
navigationBar.scrollEdgeAppearance = navigationBar.standardAppearance = app;

Keep in mind as well that you can also customize the standardAppearance and scrollEdgeAppearance of a specific UINavigationItem if your goal is only to change the appearance for a single view controller.

As for the UIScrollView comment above, if you do have a scroll view, but UIKit is not finding it (i.e. your bars are not responding to scroll it), we also added -[UIViewController setContentScrollView:forEdge:] to allow you to directly specify the scroll view to use.

  • I have the same problem in swiftUI, can you give me an example in swiftUI?

Add a Comment

Replies

As of iOS 15, UINavigationBar, UIToolbar, and UITabBar will use their scrollEdgeAppearance when your view controller's associated scroll view is at the appropriate edge (or always if you don't have a UIScrollView in your hierarchy, more on that below).

You must adopt the UIBarAppearance APIs (available since iOS 13, specializations for each bar type) to customize this behavior. UIToolbar and UITabBar add scrollEdgeAppearance properties for this purpose in iOS 15.

For your specific case, the customization code looks something like this:

UINavigationBarAppearance *app = [UINavigationBarAppearance new];
[app configureWithOpaqueAppearance];
app.backgroundColor = UIColor.redColor;
navigationBar.scrollEdgeAppearance = navigationBar.standardAppearance = app;

Keep in mind as well that you can also customize the standardAppearance and scrollEdgeAppearance of a specific UINavigationItem if your goal is only to change the appearance for a single view controller.

As for the UIScrollView comment above, if you do have a scroll view, but UIKit is not finding it (i.e. your bars are not responding to scroll it), we also added -[UIViewController setContentScrollView:forEdge:] to allow you to directly specify the scroll view to use.

  • I have the same problem in swiftUI, can you give me an example in swiftUI?

Add a Comment