簡體   English   中英

導航欄的實時模糊效果

[英]Real time blur effect for Navigation Bar

如何實現導航欄的實時模糊效果,就像 iPhone 中的 Trailers 應用一樣。

即,當您滾動時,導航欄后面的內容應該會變得模糊。 請幫我一些代碼。

謝謝!

我想達到這樣的效果:-

在此處輸入圖像描述

從 iOS 8.0 版本開始,Apple 引入了新的類UIVisualEffectView 等,以在視圖上添加半透明和模糊效果。

在這里,您可以如何使用它為導航欄或任何其他UIView添加模糊效果:

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

目標 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.
}

更新:

如果您發現在導航欄上添加模糊效果后,導航按鈕不可見,請在添加模糊視圖代碼后添加以下行。

迅速:

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

目標 C:

[self.navigationController.navigationBar sendSubviewToBack:visualEffectView];

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

注意:在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];

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

我已經添加了@Kampai的、 @Damasio的以及我的調整來解決我的問題(與pushNavigation相關)。代碼將支持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)

}

如果在@Kampai 回答后您的狀態欄沒有生效,請添加以下內容:

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

本主題中解決的問題

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

    }

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

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

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

 UINavigationBar.appearance().shadowImage = UIImage()

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

 UINavigationBar.appearance().translucent = true

現在它對我有用

重點說明:在您實現上述代碼以添加模糊視圖后,1. 您需要將您的模糊視圖發送回以顯示其他內容 2. 您需要將您的模糊視圖用戶交互設置為 false 以便能夠點擊項目導航欄。

iOS NavigationBar 模糊效果

let navigationBar = self.navigationController?.navigationBar
if #available(iOS 13.0, *) {
    navigationBar?.standardAppearance.backgroundColor = .clear
    navigationBar?.standardAppearance.backgroundEffect = UIBlurEffect(style: .systemMaterial)
}

不要忘記將您的UITableView與 superview 對齊(非安全區域)

這是上面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()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM