How can I make this part of the app (the Navigation Bar) translucent? I don't want it to be fully transparent, I want it to show the website content's colours and be blurred.
Link with screenshot: iPhone 12 simulator with Navigation Bar Opaque
I have looked at tens of possibilities and none worked:
let bounds = self.navigationController?.navigationBar.bounds as CGRect!
let visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .Light))
visualEffectView.frame = bounds
self.navigationController?.navigationBar.addSubview(visualEffectView)
self.navigationController.navigationBar.translucent = YES;
I also tried:
let blurEffect = UIBlurEffect(style: UIBlurEffect.Style.dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = (self.navigationController?.navigationBar.bounds)!
self.navigationController?.navigationBar.addSubview(blurEffectView)darkUIBlurEffect.Style
Also this:
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default) //UIImage.init(named: "transparent.png")
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.isTranslucent = true
self.navigationController?.view.backgroundColor = .clear
And this:
self.navigationController?.navigationBar.isTranslucent = true
I also tried using the Main.storyboard's Attributes Inspector and ticked Translucent.
Attributes Inspector tab on Navigation Bar in Main.storyboard
No method worked. What should I do?
Try this:
extension UIViewController {
func blurNav(withAlpha alpha:CGFloat = 1.0 ) {
let statusBarHeight = view.window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0
let rect = navigationController?.navigationBar.bounds.insetBy(dx: 0, dy: -(statusBarHeight)).offsetBy(dx: 0, dy: -(statusBarHeight)) ?? .zero
let blurView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
blurView.frame = rect
blurView.isUserInteractionEnabled = false
blurView.alpha = alpha
blurView.layer.zPosition = -1
blurView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationController?.navigationBar.addSubview(blurView)
navigationController?.navigationBar.sendSubviewToBack(blurView)
}
}
Usage:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
blurNav(withAlpha: 0.8)
}
I use this code to blur navigation bar:
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)
But my back button doesn't work and other button doesn't appear. How to fix it?
Just you should disable "isUserInteractionEnabled" to your visualEffectView
add the following line:
visualEffectView.layer.zPosition = -1;
visualEffectView.isUserInteractionEnabled = false
Similar to this:
How to make a Navigation Bar and Status Bar blurred (UIBlurEffect)? iOS, Swift 3
but we'd like to apply the UIBlurEffect on the StatusBar only, not the navigationbar. Is this possible?
You can get your statusBar view by following code, then try add to visual effect like here
let statWindow = UIApplication.shared.value(forKey:"statusBarWindow") as! UIView
let statusBar = statWindow.subviews[0] as UIView
// statusBar.backgroundColor = UIColor(red: 23 / 255.0, green: 0 / 255.0, blue: 154 / 255.0, alpha: 0.7)
statusBar.backgroundColor = UIColor(red: 213 / 255.0, green: 0 / 255.0, blue: 0 / 255.0, alpha: 0.7)
let statWindow = UIApplication.shared.value(forKey:"statusBarWindow") as! UIView
let statusBar = statWindow.subviews[0] as UIView
statusBar.backgroundColor = UIColor.clear
let blur = UIBlurEffect(style:.dark)
let visualeffect = UIVisualEffectView(effect: blur)
visualeffect.frame = statusBar.frame
//statusBar.addSubview(visualeffect)
visualeffect.alpha = 0.5
self.view.addSubview(visualeffect)
try this
iOS 14/iOS 13 solution: You can get your statusBar blur effect, by following code in your viewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
let blurryEffect = UIBlurEffect(style: .regular)
let blurredStatusBar = UIVisualEffectView(effect: blurryEffect)
blurredStatusBar.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(blurredStatusBar)
blurredStatusBar.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
blurredStatusBar.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
blurredStatusBar.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
blurredStatusBar.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true }
Sample Image
Real time blur effect for Navigation Bar
Tried the solution mentioned in the above post,
AppDelegate.swift
// Sets background to a blank/empty image
UINavigationBar.appearance().setBackgroundImage(UIImage(), forBarMetrics: .Default)
// Sets shadow (line below the bar) to a blank image
UINavigationBar.appearance().shadowImage = UIImage()
// Sets the translucent background color
UINavigationBar.appearance().backgroundColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.0)
// Set translucent. (Default value is already true, so this can be removed if desired.)
UINavigationBar.appearance().translucent = true
RootVC.swift
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.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.
}
In viewDidLoad used self.addBlurEffect.
Problem, is status bar is still not blurred, and the blur effect is restricted only to RootVC.swift.
How can I extend it to all sub VCs?
Give this a shot:
bounds.offsetInPlace(dx: 0.0, dy: -20.0)
bounds.size.height = bounds.height + 20.0
Found it here
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 the navigation bar.
Please help me with some code.
Thanks!
I want to achieve an effect like this:-
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];
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()
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
I've added #Kampai's,#Damasio's with my tweaks to resolve my issues(which was pushNavigation related).Code will support Swift 4.0+, iOS9, Xcode 9
In your ViewController's ViewDidLoad(), just call
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)
}
If, after #Kampai answer you get the status bar not getting in the effect, add this:
bounds.offsetInPlace(dx: 0.0, dy: -20.0)
bounds.size.height = bounds.height + 20.0
Question addressed in this topic.
Swift 5, iOS 13 +
You can use UINavigationBarAppearance() in AppDelegate file. And don't forget set appearance for not scrolling mode. For me it works perfect with 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
}
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)
}
I first added addBlurEffect() method and then in AppDelegate, I added
UINavigationBar.appearance().setBackgroundImage(UIImage(), forBarMetrics: .Default)
UINavigationBar.appearance().shadowImage = UIImage()
UINavigationBar.appearance().backgroundColor = UIColor.clearColor()
UINavigationBar.appearance().translucent = true
Now it works for me
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.
iOS NavigationBar Blur Effect
let navigationBar = self.navigationController?.navigationBar
if #available(iOS 13.0, *) {
navigationBar?.standardAppearance.backgroundColor = .clear
navigationBar?.standardAppearance.backgroundEffect = UIBlurEffect(style: .systemMaterial)
}
Don't forget to align your UITableView to superview(not Safe area)
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()