0

How can I make the navigation bar be both translucent while also having a tint to it, as illustrated in the image below:

enter image description here

I also want it to keep the default blur effect of a translucent nav bar (so I don't want it to look exactly like the picture, cause I want the blur effect too.) I feel like this should be pretty easy but I've spent an hour looking for a solution and nothing works the way I want it to. Also, I would prefer an Interface Builder solution, but if there isn't one than swift is fine too.

Josh Hadik
  • 403
  • 5
  • 16

3 Answers3

1

The colour changing part comes from here. I just added the blur part from here. I do not know if it is the best solution for blur, but it is working. You will need to subclass your navigation bar, but nothing painful. Found it better if blur view had slightly dropped alpha, you will have to play with this a little.

extension UIColor {
    func toImage() -> UIImage? {
        return toImageWithSize(size: CGSize(width: 1, height: 1))
    }
    func toImageWithSize(size: CGSize) -> UIImage? {
        UIGraphicsBeginImageContext(size)

        if let ctx = UIGraphicsGetCurrentContext() {
            let rectangle = CGRect(x: 0, y: 0, width: size.width, height: size.height)
            ctx.setFillColor(self.cgColor)
            ctx.addRect(rectangle)
            ctx.drawPath(using: .fill)
            let colorImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return colorImage
        } else {
            return nil
        }
    }
}

extension UIImage {
    func imageWithAlpha(alpha: CGFloat) -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        draw(at: CGPoint.zero, blendMode: .normal, alpha: alpha)
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage
    }
}

class CustomNavBar: UINavigationBar {

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        setBackgroundImage(UIColor.blue.toImage()?.imageWithAlpha(alpha: 0.5), for: .default)
        addBlurEffect()
    }

    func addBlurEffect() {
        let visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
        var frame = bounds
        frame.origin.y -= 20
        frame.size.height += 20
        visualEffectView.frame = frame
        visualEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        visualEffectView.alpha = 0.9
        insertSubview(visualEffectView, at: 0)
        sendSubview(toBack: visualEffectView)
    }
}
Luzo
  • 1,336
  • 10
  • 15
  • 1
    Good solution. Only addition I had to make was to set the z position of visualEffectView to -1 in the addBlurEffect method (visualEffectView.layer.zPosition = -1) otherwise the navigation title shows up behind the blur effect, ( I guess this is only a problem in iOS 11. I found this solution [here](https://stackoverflow.com/a/47030102/3985721) ) – Josh Hadik Nov 12 '17 at 19:01
0

Just set the colour of the Navigation Bar and then the transparency.

navigationController?.navigationBar.barTintColor = UIColor.green
navigationController?.navigationBar.alpha = 0.5

That should do it.

Niall Kehoe
  • 416
  • 5
  • 17
0

Just select "Navigation Bar" of UINavigationController (not NavigationItem of other ViewControllers) in the interface builder and change "barTintColor"

enter image description here

arturdev
  • 10,884
  • 2
  • 39
  • 67
  • I tried this but when I set the bar tint it results in a solid background color, not a semi-transparent one like in the picture I posted. – Josh Hadik Nov 11 '17 at 21:20