导航栏的实时模糊效果

时间:2014-12-05 04:35:53

标签: ios objective-c swift uinavigationcontroller uinavigationbar

如何像iPhone中的预告片应用一样实现导航栏的实时模糊效果。

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

谢谢!

我想达到这样的效果: -

enter image description here

10 个答案:

答案 0 :(得分:41)

Apple推出了新的类UIVisualEffectView以及更多内容,以便在iOS 8.0版本的视图中添加半透明效果和模糊效果。

在此处,您可以使用它向导航栏或任何其他UIView添加模糊效果:

Swift 2.1编辑

func addBlurEffect() {
    let bounds = self.navigationController?.navigationBar.bounds as CGRect!
    let visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
    visualEffectView.frame = bounds!
    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 above code to add effects to custom view.
}

目标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 above code to add effects to custom view.
}

<强>更新

如果您在navigationBar上添加模糊效果后发现导航按钮不可见,则在添加blurView代码后添加下面的行。

夫特:

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

目标C:

[self.navigationController.navigationBar sendSubviewToBack:visualEffectView];

答案 1 :(得分:6)

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

self.visualEffectView.layer.zPosition = -1;

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代码

  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

答案 2 :(得分:6)

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

用法

navigationController?.navigationBar.installBlurEffect()

答案 3 :(得分:4)

我添加了 @Kampai @Damasio 以及我的调整以解决我的问题(与 pushNavigation 相关) .Code将支持 Swift 4.0 + iOS9,Xcode 9

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

即可
addBlurEffect(toView: self.navigationController?.navigationBar)

功能:

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

}

答案 4 :(得分:3)

如果在@Kampai回答后你没有获得效果的状态栏,请添加:

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

this topic中提到的问题。

答案 5 :(得分:2)

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)

    }

答案 6 :(得分:0)

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

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

 UINavigationBar.appearance().shadowImage = UIImage()

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

 UINavigationBar.appearance().translucent = true

现在它对我有用

答案 7 :(得分:0)

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

答案 8 :(得分:0)

Swift 5、iOS 13 +

您可以在 AppDelegate 文件中使用 UINavigationBarAppearance()。并且不要忘记为非滚动模式设置外观。对我来说,它与 navigationBar.prefersLargeTitles 完美搭配。

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    let appearance = UINavigationBarAppearance()
    appearance.configureWithTransparentBackground()
    appearance.backgroundColor = UIColor.clear
    appearance.backgroundEffect = UIBlurEffect(style: .light) // or dark
    
    let scrollingAppearance = UINavigationBarAppearance()
    scrollingAppearance.configureWithTransparentBackground()
    scrollingAppearance.backgroundColor = .white // your view (superview) color
    
    UINavigationBar.appearance().standardAppearance = appearance
    UINavigationBar.appearance().scrollEdgeAppearance = scrollingAppearance
    UINavigationBar.appearance().compactAppearance = scrollingAppearance
    
    return true
}

答案 9 :(得分:-1)

这是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
    }
}

用法类似:

navigationController?.toolbar.toolBarBlurEffect()