Real time blur effect for Navigation Bar

后端 未结 9 2244
不思量自难忘°
不思量自难忘° 2020-11-28 05:21

How to achieve the real time blurring effect for the navigation bar just like the Trailers app in iPhone.

i.e As you scroll the contents should get blurred behind th

相关标签:
9条回答
  • 2020-11-28 06:00

    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];
    
    0 讨论(0)
  • 2020-11-28 06:00

    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()
    
    0 讨论(0)
  • 2020-11-28 06:01

    Key note: after u implement above code to add blur view, 1. U need to send your blur view to back to show other things 2. U need to set your blur view user interaction to be false to be able to tap the items on the navigation bar.

    0 讨论(0)
  • 2020-11-28 06:11

    This is neoneye's solution from above, which works perfectly, applied to a UIToolbar.

    extension UIToolbar {
        func toolBarBlurEffect() {
            isTranslucent = true
            setBackgroundImage(UIImage(), forToolbarPosition: .any, barMetrics: .default)
            let statusBarHeight: CGFloat = UIApplication.shared.statusBarFrame.height
            var blurFrame = bounds
            blurFrame.size.height += statusBarHeight
            let blurView  = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
            blurView.isUserInteractionEnabled = false
            blurView.frame = blurFrame
            blurView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
            addSubview(blurView)
            blurView.layer.zPosition = -1
        }
    }
    

    Usage is similar:

    navigationController?.toolbar.toolBarBlurEffect()
    
    0 讨论(0)
  • 2020-11-28 06:14

    SWIFT 3:

    func addBlurEffect(toView view:UIView?) {
            // Add blur view
            guard let view = view else { return }
    
            //This will let visualEffectView to work perfectly
            if let navBar = view as? UINavigationBar{
                navBar.setBackgroundImage(UIImage(), for: .default)
                navBar.shadowImage = UIImage()
            }
    
            var bounds = view.bounds
            bounds.offsetBy(dx: 0.0, dy: -20.0)
            bounds.size.height = bounds.height + 20.0
    
            let blurEffect = UIBlurEffect(style: .dark)
            let visualEffectView = UIVisualEffectView(effect: blurEffect)
    
            visualEffectView.isUserInteractionEnabled = false
            visualEffectView.frame = bounds
            visualEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
            view.insertSubview(visualEffectView, at: 0)
    
        }
    
    0 讨论(0)
  • 2020-11-28 06:16

    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
    
    0 讨论(0)
提交回复
热议问题