ios 导航栏的实时模糊效果

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27308842/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 03:54:28  来源:igfitidea点击:

Real time blur effect for Navigation Bar

iosobjective-cswiftuinavigationcontrolleruinavigationbar

提问by Shikhar varshney

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

如何实现导航栏的实时模糊效果,就像 iPhone 中的 Trailers 应用程序一样。

i.e As you scroll the contents should get blurred behind the navigation bar. Please help me with some code.

即当您滚动时,导航栏后面的内容应该会变得模糊。请帮我写一些代码。

Thanks!

谢谢!

I want to achieve an effect like this:-

我想达到这样的效果:-

enter image description here

在此处输入图片说明

回答by Kampai

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

从 iOS 8.0 版本开始,Apple 引入了新的类UIVisualEffectView 等,以在视图上添加半透明和模糊效果。

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

在这里您可以如何使用它为导航栏或任何其他添加模糊效果UIView

Swift 5

斯威夫特 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:

目标 C 代码:

- (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:

目标 C:

[self.navigationController.navigationBar sendSubviewToBack:visualEffectView];

回答by neoneye

Swift 4

斯威夫特 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()

回答by Martin Le

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

注意:在iOS 11 上,功能sendSubviewToBack无法正常工作。为了实现这一点,我们应该使用zPosition将模糊效果视图放置在其他视图下。

self.visualEffectView.layer.zPosition = -1;

Objective-C code

Objective-C 代码

[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

斯威夫特 4 代码

  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

回答by Rafat touqir Rafsun

I've added @Kampai's,@Damasio's with my tweaks to resolve my issues(which was pushNavigationrelated).Code will support Swift 4.0+, iOS9, Xcode 9

我已经添加了@Kampai的、@Damasio的以及我的调整来解决我的问题(与pushNavigation相关)。代码将支持Swift 4.0+iOS9、Xcode 9

In your ViewController's ViewDidLoad(), just call

在您的 ViewController 的 ViewDidLoad() 中,只需调用

addBlurEffect(toView: self.navigationController?.navigationBar)

function:

功能:

   //MARK :- It can be used in navBarGlassEffect view
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)

}

回答by Damasio

If, after @Kampai answer you get the status bar not getting in the effect, add this:

如果在@Kampai 回答后您的状态栏没有生效,请添加以下内容:

bounds.offsetInPlace(dx: 0.0, dy: -20.0)
bounds.size.height = bounds.height + 20.0

Question addressed in this topic.

本主题中解决的问题

回答by Maksim Kniazev

SWIFT 3:

快速 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)

    }

回答by Developer Sheldon

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.

重点说明:在你实现上面的代码添加模糊视图后,1.你需要将你的模糊视图发送回来以显示其他东西 2.你需要将你的模糊视图用户交互设置为假以便能够点击项目导航栏。

回答by alitosuner

I first added addBlurEffect() method and then in AppDelegate, I added

我首先添加了 addBlurEffect() 方法,然后在 AppDelegate 中添加了

 UINavigationBar.appearance().setBackgroundImage(UIImage(), forBarMetrics: .Default)

 UINavigationBar.appearance().shadowImage = UIImage()

 UINavigationBar.appearance().backgroundColor = UIColor.clearColor()

 UINavigationBar.appearance().translucent = true

Now it works for me

现在它对我有用

回答by Gibson

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

这是上面neoneye的解决方案,它完美地适用于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()