2

I implemented a gradient in my navigation bar with the help of this answer. However, the gradient excludes the search bar.

current

But this is what I would like: desired

Any idea what seems to be the problem? Big thank you for any help someone can offer. I'll share my code below.

extension UINavigationBar {

    func setGradientBackground(colors: [UIColor]) {

        var updatedFrame = bounds
        updatedFrame.size.height += 20
        let gradientLayer = CAGradientLayer(frame: updatedFrame, colors: colors)

        setBackgroundImage(gradientLayer.createGradientImage(), for: UIBarMetrics.default)
    }
}


extension CAGradientLayer {

    convenience init(frame: CGRect, colors: [UIColor]) {
        self.init()
        self.frame = frame
        self.colors = []
        for color in colors {
            self.colors?.append(color.cgColor)
        }
        startPoint = CGPoint(x: 0, y: 0)
        endPoint = CGPoint(x: 0, y: 1)
    }

    func createGradientImage() -> UIImage? {

        var image: UIImage? = nil
        UIGraphicsBeginImageContext(bounds.size)
        if let context = UIGraphicsGetCurrentContext() {
            render(in: context)
            image = UIGraphicsGetImageFromCurrentImageContext()
        }
        UIGraphicsEndImageContext()
        return image
    }

}

My ViewController:

override func viewDidLoad() {
    super.viewDidLoad()

    self.navigationBarGradient(colors: [UIColor.init(hex: "0089FC" ), 
UIColor.init(hex: "56ACF5" )])

    if #available(iOS 11.0, *) {
        navigationItem.searchController = searchController

    }
}
  private func navigationBarGradient(colors: [UIColor]) {
        navigationController?.navigationBar.setGradientBackground(colors: colors)
    }
degenPenguin
  • 725
  • 1
  • 8
  • 23

3 Answers3

2

I believe the search bar and the nav bar are two separate elements so your gradient is only effecting one. You can set them both to clear and then put another view or label element behind (add constraints) with the gradient you're looking for.

for the searchBar you want to set both the barTintColor and the backgroundImage with the following code.

override func viewDidLoad() {
    self.searchBar.barTintColor = UIColor.clear
    self.searchBar.backgroundImage = UIImage()
    self.navBar.backgroundColor = UIColor.clear
}
  • Frustratingly, when I set the navigation's barTintColor, it affects both the status bar and navigation bar. But I will try this suggestion. – degenPenguin Jan 05 '18 at 03:58
  • There are probably multiple solutions to this problem but for me, this was the path of least resistance. Thank you – degenPenguin Jan 06 '18 at 22:35
0

Please check this Sample Code from Apple on how to do this and other modifications on the navigation bar.

That being said, if you don't need any of the other navigation bar functionality like left and right buttons for instance, it would be much simpler to just hide the nav bar in this particular view and have a custom view in it's place.

Ahmed Hamed
  • 504
  • 1
  • 3
  • 11
0

In the method I can think of, the use of material resources is one of the most simple, if make the upper control transparent may effect is not very good

Tim
  • 1,528
  • 1
  • 11
  • 8