Home > other >  Incorrect navigation bar colour in limited library picker on iOS 15
Incorrect navigation bar colour in limited library picker on iOS 15

Time:11-02

I am trying to set the colour of the navigation bar in the limited library picker. To do this I have the following lines in AppDelegate.application:didFinishLaunchingWithOptions:

if (@available(iOS 13, *)) {
    UINavigationBarAppearance *navigationBarAppearance = [UINavigationBarAppearance new];
    navigationBarAppearance.backgroundColor = UIColor.yellowColor;

    [UINavigationBar appearance].standardAppearance = navigationBarAppearance;
    [UINavigationBar appearance].scrollEdgeAppearance = navigationBarAppearance;
}

[UINavigationBar appearance].barTintColor = UIColor.greenColor;
[UINavigationBar appearance].backgroundColor = UIColor.redColor;

This sets the colour to green as I would expect on iOS 14: enter image description here

But a faded red colour on iOS 15: enter image description here

How can I set the colour correctly on iOS 15?

EDIT: Minimum reproducible example (Set up a new iOS project with single view controller and add the NSPhotoLibraryUsageDescription key to info.plist)

import UIKit
import Photos
import PhotosUI

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        PHPhotoLibrary.requestAuthorization(for: .readWrite, handler: { _ in})
        PHPhotoLibrary.shared().presentLimitedLibraryPicker(from: self)
    }
}

AppDelegate.swift:

import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        if #available(iOS 13, *) {
            let navigationBarAppearance = UINavigationBarAppearance()
            navigationBarAppearance.backgroundColor = UIColor.yellow

            UINavigationBar.appearance().standardAppearance = navigationBarAppearance
            UINavigationBar.appearance().scrollEdgeAppearance = navigationBarAppearance
        }

        UINavigationBar.appearance().barTintColor = UIColor.green
        UINavigationBar.appearance().backgroundColor = UIColor.red
        return true
    }

    // MARK: UISceneSession Lifecycle

    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        // Called when a new scene session is being created.
        // Use this method to select a configuration to create the new scene with.
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }
}

EDIT: Objective-C version of Matt's solution:

UIGraphicsImageRenderer * imageRenderer = [[UIGraphicsImageRenderer alloc]initWithSize:CGSizeMake(1, 1)];
UIImage *image = [imageRenderer imageWithActions:^(UIGraphicsImageRendererContext *context){
    [TOOLBAR_BACKGROUND_COLOUR setFill];
    [context fillRect:CGRectMake(0, 0, 1, 1)];
}];
[[UINavigationBar appearance] setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];

CodePudding user response:

The way to get completely control over a navigation bar's color is to use a background image. Make an image renderer. Fill the context with solid red and extract the image from the renderer. Call setBackgroundImage on the appearance proxy.

I don't have time to translate the code from Swift to Objective-C so I leave it up to you:

    let rend = UIGraphicsImageRenderer(size:.init(width:100, height:100))
    let im = rend.image {
        con in
        UIColor.red.setFill()
        con.fill(.init(x: 0, y: 0, width: 100, height: 100))
    }
    UINavigationBar.appearance().setBackgroundImage(im, for: .default)
  • Related