skip to Main Content

I’m setting the image of the navigation bar to a gradient. This works perfectly on all models except for iPhone 12 mini.

I’ve tried calling this on my main view controller in ViewWillAppear, viewDidAppear, and ViewDidLoad

enter image description here

Here’s what it looks like on all other models

enter image description here

    func setNavGradiant(){
    guard let navigationController = self.navigationController else {print("❇️♊️>>>(#file) (#line): guard let failed<<<"); return}
    let gradientLayer = CAGradientLayer()
    var updatedFrame = navigationController.navigationBar.bounds
    updatedFrame.size.height += UIApplication.shared.windows[0].windowScene?.statusBarManager?.statusBarFrame.height ?? 0

   
   
    gradientLayer.frame = updatedFrame
    gradientLayer.colors = [ #colorLiteral(red: 0.4392156899, green: 0.01176470611, blue: 0.1921568662, alpha: 1).cgColor,  #colorLiteral(red: 0.2196078449, green: 0.007843137719, blue: 0.8549019694, alpha: 1).cgColor] // start color and end color
    gradientLayer.startPoint = CGPoint(x: 0.5, y: 0.0) // vertical gradient start
    gradientLayer.endPoint = CGPoint(x: 0.5, y: 1.0)
    UIGraphicsBeginImageContext(gradientLayer.bounds.size)
    gradientLayer.render(in: UIGraphicsGetCurrentContext()!)
    let image = UIGraphicsGetImageFromCurrentImageContext()
    
    UIGraphicsEndImageContext()
    
    self.navigationController?.navigationBar.setBackgroundImage(image, for: UIBarMetrics.default)
    self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor(#colorLiteral(red: 0.9579688907, green: 0.9579688907, blue: 0.9579688907, alpha: 1))]
}

2

Answers


  1. You will probably have better results by subclassing UINavigationController:

    class MyNavigationController: UINavigationController {
    
        let gradient = CAGradientLayer()
    
        override func viewDidLoad() {
            super.viewDidLoad()
        
            gradient.frame = navigationBar.bounds
            
            gradient.colors = [ #colorLiteral(red: 0.4392156899, green: 0.01176470611, blue: 0.1921568662, alpha: 1).cgColor,  #colorLiteral(red: 0.2196078449, green: 0.007843137719, blue: 0.8549019694, alpha: 1).cgColor] // start color and end color
            gradient.startPoint = CGPoint(x: 0.5, y: 0.0) // vertical gradient start
            gradient.endPoint = CGPoint(x: 0.5, y: 1.0)
            
            if let image = getImageFrom(gradientLayer: gradient) {
                navigationBar.setBackgroundImage(image, for: UIBarMetrics.default)
            }
    
        }
    
        func getImageFrom(gradientLayer:CAGradientLayer) -> UIImage? {
            var gradientImage:UIImage?
            UIGraphicsBeginImageContext(gradientLayer.frame.size)
            if let context = UIGraphicsGetCurrentContext() {
                gradientLayer.render(in: context)
                gradientImage = UIGraphicsGetImageFromCurrentImageContext()?.resizableImage(withCapInsets: UIEdgeInsets.zero, resizingMode: .stretch)
            }
            UIGraphicsEndImageContext()
            return gradientImage
        }
    
    }
    
    Login or Signup to reply.
  2. Try calling:

    DispatchQueue.main.async {
                self.setNeedsStatusBarAppearanceUpdate()
            }
    

    after your setup is done. Should work without dispatching to main thread, but I had previously caught issues of things called from lifecycle methods not being on the main thread. So another thing to check is to make sure you are running the updates on the main thread.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search