Real time blur effect for Navigation Bar Real time blur effect for Navigation Bar ios ios

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];


Swift 4

extension UINavigationBar {    func installBlurEffect() {        isTranslucent = true        setBackgroundImage(UIImage(), for: .default)        let statusBarHeight: CGFloat = UIApplication.shared.statusBarFrame.height        var blurFrame = bounds        blurFrame.size.height += statusBarHeight        blurFrame.origin.y -= statusBarHeight        let blurView  = UIVisualEffectView(effect: UIBlurEffect(style: .light))        blurView.isUserInteractionEnabled = false        blurView.frame = blurFrame        blurView.autoresizingMask = [.flexibleWidth, .flexibleHeight]        addSubview(blurView)        blurView.layer.zPosition = -1    }}

Usage

navigationController?.navigationBar.installBlurEffect()


Noted: on iOS 11, function sendSubviewToBack does not work normally. In order to achieve that, we should use zPosition to place the blur effect view under other views.

self.visualEffectView.layer.zPosition = -1;

Objective-C code

[self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];    self.navigationController.navigationBar.shadowImage = [UIImage new];    self.navigationController.navigationBar.barTintColor = [UIColor whiteColor];    self.navigationController.navigationBar.backgroundColor = [UIColor clearColor];    self.navigationController.navigationBar.translucent = YES;    // Add blur view    CGRect bounds = self.navigationController.navigationBar.bounds;    bounds.size.height += 20;    bounds.origin.y -= 20;    _visualEffectView = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];    self.visualEffectView.frame = bounds;    self.visualEffectView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;    self.visualEffectView.userInteractionEnabled = NO;    self.visualEffectView.layer.zPosition = -1;    [self.navigationController.navigationBar addSubview:self.visualEffectView];    [self.navigationController.navigationBar sendSubviewToBack:self.visualEffectView];

Swift 4 code

  self.navigationController?.navigationBar.isTranslucent = true    self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)    let visualEffectView   = UIVisualEffectView(effect: UIBlurEffect(style: .light))    var bounds = view.bounds    bounds.size.height += 20    bounds.origin.y -= 20    visualEffectView.isUserInteractionEnabled = false    visualEffectView.frame = bounds    visualEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]    self.navigationController?.navigationBar.addSubview(visualEffectView)    visualEffectView.layer.zPosition = -1