jjatie
jjatie

Reputation: 5332

Make UINavigationBar have a gradient background using UIAppearance

Following this question, I am able to make a background gradient for a UINavigationBar, however when I try to set it through UIAppearance, the app crashes in the didFinishLaunching because there is no current CGContext. How can I get around this and still have all my UIAppearance code in the app delegate?

The code being called just before return true in the didFinishLaunching:

private func setNavBarAppearance() {
    let titleAttributes: [NSAttributedStringKey: Any] = [.foregroundColor: UIColor.white]
    UINavigationBar.appearance().titleTextAttributes = titleAttributes
    UINavigationBar.appearance().barTintColor = .white
    UINavigationBar.appearance().tintColor = .white
    UINavigationBar.appearance().makeTransparent()

    // Set gradient
    let colors = [UIColor.lavender.cgColor, UIColor.mint.cgColor]
    let gradientLayer = CAGradientLayer()
    gradientLayer.frame = UINavigationBar.appearance().bounds
    gradientLayer.colors = colors
    gradientLayer.startPoint = CGPoint(x: 0, y: 0.5)
    gradientLayer.endPoint = CGPoint(x: 0.5, y: 0.5)

    let image = UIImage(layer: gradientLayer)
    UINavigationBar.appearance().setBackgroundImage(image, for: .default)
}

Upvotes: 0

Views: 358

Answers (1)

jjatie
jjatie

Reputation: 5332

When calling UIGraphicsBeginImageContext, you must provide a non-zero CGRect. In my case I was setting the frame to UINavigationBar.appearance().bounds which is a zero rect in the app delegate. To get around this I simply set the gradient frame to CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 1)

Upvotes: 1

Related Questions