如何使导航栏和状态栏模糊(UIBlurEffect)?iOS,Swift 3

3
如何使导航栏和状态栏模糊(UIBlurEffect)?当我通过点击图像向下滚动(滚动视图)到其他图片时,这张图片(在这种情况下是一个白色的机器)会简单地消失在导航栏下面,需要让这个图像在导航栏下面可见并带有UIBlurEffect效果。 没有UIBlurEffect 我已经尝试过了,但没有成功:
func addBlurEffect() {
// Add blur view
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)
self.navigationController?.navigationBar.sendSubview(toBack: visualEffectView)
visualEffectView.isUserInteractionEnabled = false }

首先,当滚动图片时,它会消失在导航栏下面。
其次,状态栏仍然是灰色的。

导航栏的UIBlurEffect效果不好,而状态栏没有UIBlurEffect效果

为了让状态栏不再是灰色的,我尝试过,但没有成功 =(

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

同样在AppDelegate中(该应用程序是用Objective-C编写的),在didFinishLaunchingWithOptions中,我尝试添加它,所有内容保持不变,没有任何更改:

[[UINavigationBar appearance] setBackgroundImage:[[UIImage alloc]init] forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setShadowImage:[[UIImage alloc]init]];
[[UINavigationBar appearance] setBackgroundColor:[UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:0.0f]];
[[UINavigationBar appearance] setTranslucent:YES];

请帮忙解决问题,我已经折腾了三天。
非常抱歉我的英语不好。

5个回答

11

将背景图片设置为导航栏,可以达到效果。在Swift 3中,以下代码对我有效。

    let visualEffectView   = UIVisualEffectView(effect: UIBlurEffect(style: .light))
    visualEffectView.frame =  (self.navigationController?.navigationBar.bounds.insetBy(dx: 0, dy: -10).offsetBy(dx: 0, dy: -10))!
    self.navigationController?.navigationBar.isTranslucent = true
    self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
    self.navigationController?.navigationBar.addSubview(visualEffectView)

输出:

输入图像描述


2
@RayKing 我曾经遇到过同样的问题。我在这里找到了解决方案:https://dev59.com/414d5IYBdhLWcg3wAOZw#27316465 只需在放置效果后添加:self.navigationController?.navigationBar.sendSubviewToBack(visualEffectView) - Romain Caron
2
此代码使用了魔术常量“-10”,可能很容易出错。 - neoneye

10

根据@Vignesh的答案,硬编码-10是一个不好的主意。比如,对于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)

我也建议创建一个UINavigationController的子类,因为这是一种良好的编程实践。代码如下:

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)

    }

}

现在,在iOS 13.0中已经弃用了'statusBarFrame':请改用窗口场景的'statusBarManager'属性。 - Antonio Adrian Chavez
嗨,如何去除这个模糊? - famfamfam

6

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
}

你也可以访问这个链接查看测试项目:https://github.com/leningradspb/BlurNavigationBar


0
这是我关于同一件事的Objective-C代码,并且它包括对iPhone X额外大的导航栏的支持。
UIVisualEffectView *fxView = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
[fxView setFrame:CGRectOffset(CGRectInset(self.navigationController.navigationBar.bounds, 0, -12), 0, -60)];
[self.navigationController.navigationBar setTranslucent:YES];
[self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarPosition:UIBarPositionAny barMetrics:UIBarMetricsDefault];
[self.navigationController.navigationBar insertSubview:fxView atIndex:1];

0

Swift 3

感谢@Vignesh的回答和@Romain Caron的评论,我结合了你们的代码,以下代码在Swift 3中适用于我

    let visualEffectView   = UIVisualEffectView(effect: UIBlurEffect(style: .light))
    visualEffectView.frame =  (self.navigationController?.navigationBar.bounds.insetBy(dx: 0, dy: -10).offsetBy(dx: 0, dy: -10))!
    self.navigationController?.navigationBar.isTranslucent = true
    self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
    self.navigationController?.navigationBar.addSubview(visualEffectView)
    self.navigationController?.navigationBar.sendSubview(toBack: visualEffectView)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接