10

I'm trying to change the background of a navigation bar by creating a layer and adding it as a sublayer to the navigation bar. However, this is only affecting the navigation bar.

1

I wan't it to affect the whole top of the screen. Code included:

let navBarLayer = StyleUtils.createGradientLayerWithColors(color: StyleUtils.Colors.SKY_BLUE, frame: (self.navigationController?.navigationBar.bounds)!)

self.navigationController?.navigationBar.layer.addSublayer(navBarLayer)

The createGradientLayerWithColors function returns a CAGradientLayer for the given frame.

What am I missing? Thank you in advance.

EDIT:

I tried Nathaniel answer, but got this:

problem

It's worth mentioning that this is also a TableView.

SOLUTION:

I found this question that helped me solve the problem.

The final correct code is:

func setNavBarColor() {

    let navBar = self.navigationController?.navigationBar

    //Make navigation bar transparent
    navBar?.setBackgroundImage(UIImage(), for: .default)
    navBar?.shadowImage = UIImage()
    navBar?.isTranslucent = true

    //Create View behind navigation bar and add gradient
    let behindView = UIView(frame: CGRect(x: 0, y:0, width: UIApplication.shared.statusBarFrame.width, height: UIApplication.shared.statusBarFrame.height + (navBar?.frame.height)!))

    let layerTop = StyleUtils.createGradientLayerWithColors(color: StyleUtils.Colors.SKY_BLUE, frame: behindView.bounds)
    behindView.layer.insertSublayer(layerTop, at: 0)

    self.navigationController?.view.insertSubview(behindView, belowSubview: navBar!)

}
Community
  • 1
  • 1
PablodeAcero
  • 399
  • 8
  • 20
  • I put this method into an extension of UINavigationController, called it initializeNavBarStyle, and it works really well! – LargeGlasses Jul 04 '17 at 16:59

2 Answers2

15

This is how I manage it.

First I set the NavigationBar to transparent:

self.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationBar.shadowImage = UIImage()
self.navigationBar.isTranslucent = true
self.navigationBar.backgroundColor = UIColor.clear

Then I add the gradient to the view behind the status bar and the navigation bar:

    let gradient = CAGradientLayer()
    gradient.frame = CGRect(x: 0, y: 0, width: UIApplication.sharedApplication().statusBarFrame.width, height: UIApplication.sharedApplication().statusBarFrame.height + self.navigationController!.navigationBar.frame.height)
    gradient.locations = [0.0,1.0]
    gradient.colors = [UIColor.anyColor().colorWithAlphaComponent(0.4).CGColor, UIColor.clearColor().CGColor]
    self.view.layer.addSublayer(gradient)
    self.view.backgroundColor = UIColor.clear
Nathaniel
  • 836
  • 9
  • 19
  • I tried your answer, but it has some problems. Please check my edit. Ps: I also used other colours for the experiment. – PablodeAcero Dec 08 '16 at 22:25
  • @PablodeAcero I added a line to the end of the NavigationBar transparent section -- try that! – Nathaniel Dec 09 '16 at 06:44
  • 1
    Hey. Your comment didn't correct the issue, but it helped me search for the solution. Thank you very much for your help! I'll mark this as the correct answer and I'll update my question with the answer. – PablodeAcero Dec 09 '16 at 13:30
0

My option:

let gradientLayer = CAGradientLayer()

let layerY = -UIApplication.shared.statusBarFrame.size.height as CGFloat

let layerHeight = (self.navigationController?.navigationBar.frame.size.height)! + UIApplication.shared.statusBarFrame.size.height as CGFloat

gradientLayer.frame = CGRect(x: 0, y: layerY, width: 1366, height: layerHeight)

gradientLayer.colors = [UIColor(red: 16/255.0, green: 57/255.0, blue: 82/255.0, alpha: 1.0).cgColor, UIColor(red: 17/255.0, green: 132/255.0, blue: 157/255.0, alpha: 1.0).cgColor]

self.navigationController?.navigationBar.layer.addSublayer(gradientLayer)

It is not better, simply just another way to do the same.

Markus
  • 1,147
  • 16
  • 26