Real Time Blur Effect for Navigation Bar

Real time blur effect for Navigation Bar

Apple has introduced new classes UIVisualEffectView and more to add translucency and blur effect on views from iOS 8.0 release.

Here how you can use it to add a blur effect to navigation bar or any other UIView:

Swift 5

func addBlurEffect() {
let bounds = self.navigationController?.navigationBar.bounds
let visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
visualEffectView.frame = bounds ?? CGRect.zero
visualEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.navigationController?.navigationBar.addSubview(visualEffectView)

// Here you can add visual effects to any UIView control.
// Replace custom view with navigation bar in the above code to add effects to the custom view.
}

Objective C Code:

- (void) addBlurEffect {
// Add blur view
CGRect bounds = self.navigationController.navigationBar.bounds;
UIVisualEffectView *visualEffectView = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
visualEffectView.frame = bounds;
visualEffectView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.navigationController.navigationBar addSubview:visualEffectView];
self.navigationController.navigationBar.backgroundColor = [UIColor clearColor];
[self.navigationController.navigationBar sendSubviewToBack:visualEffectView];

// Here you can add visual effects to any UIView control.
// Replace custom view with navigation bar in the above code to add effects to the custom view.
}

UPDATE:

If you find that after adding blur effect on navigationBar, navigation buttons are not visible then add below line after adding blurView code.

Swift:

self.navigationController?.navigationBar.sendSubview(toBack: visualEffectView)

Objective C:

[self.navigationController.navigationBar sendSubviewToBack:visualEffectView];

Real time blur effect for Navigation Bar - Status bar not getting in

It's partly because you set the visual effect view's frame to the navigation bar's bounds. What you see in the screen shot are the navigation bar's bounds. So, you might be able to compensate by giving your visual effect view a different frame, i.e. move its origin up 20 points and increase its height.

It's a little unclear to me, though, why you don't just make the navigation bar translucent. Navigation bar translucency is the blur effect, and it is supported. What you're doing — adding a subview to the navigation bar — is not.

How to make a Navigation Bar and Status Bar blurred (UIBlurEffect)? iOS, Swift 3

Going off @Vignesh answer it's a bad idea to hard code -10. For example this won't be sized correctly for iphone X.

// Find size for blur effect.
let statusBarHeight = UIApplication.shared.statusBarFrame.size.height
let bounds = self.navigationController?.navigationBar.bounds.insetBy(dx: 0, dy: -(statusBarHeight)).offsetBy(dx: 0, dy: -(statusBarHeight))
// Create blur effect.
let visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
visualEffectView.frame = bounds
// Set navigation bar up.
self.navigationController?.navigationBar.isTranslucent = true
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.addSubview(visualEffectView)
self.navigationController?.navigationBar.sendSubview(toBack: visualEffectView)

I would also recommend creating a subclass of UINavigationController as it's good practice. Something like this:

final class func MyCustomNavigation: UINavigationController {

override func viewDidLoad() {

// Find size for blur effect.
let statusBarHeight = UIApplication.shared.statusBarFrame.size.height
let bounds = navigationBar.bounds.insetBy(dx: 0, dy: -(statusBarHeight)).offsetBy(dx: 0, dy: -(statusBarHeight))
// Create blur effect.
let visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
visualEffectView.frame = bounds
// Set navigation bar up.
navigationBar.isTranslucent = true
navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationBar.addSubview(visualEffectView)
navigationBar.sendSubview(toBack: visualEffectView)

}

}

How to apply blur effect on a navbar in css

Use backdrop-filter property to do this or use the trivial way of using two divs (refer to Filtering Background with and without backdrop-filter

For Example:

.foreground {
backdrop-filter: blur(0.8);
}

Note: This doesn't have the full Browser support.

One trick I want to share here, Since you want to achieve the same styling as on the Apple website, simply make use of Developer Console. Hit CTRL+SHIFT+I and see how Apple has applied the CSS for the Navbar. This way you can learn new things and achieve what you seek :)

How do you make a navigation bar colored and translucent (iOS)?

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)
}
}


Related Topics



Leave a reply



Submit