0

I have an application with a UINavigationController and a UITabBarController. Inside the UITabBarController is a button which should present a modal view, for which I want to black out the entire screen with a faded background (black with .5 alpha).

I do this with a UIView() as follows, this is set inside the UITabBarController class:

let fadeBackground: UIView = {
    let fadeBackground = UIView(frame: self.view.frame)
    fadeBackground.backgroundColor = UIColor.black
    fadeBackground.alpha = 0.5
    return fadeBackground
}()

I then add it to my view with view.addSubview(fadeBackground). This, however, returns the faded background above everything, including the UINavigationController and UITabBarController, but it does not overlay the status bar. To illustrate: entire screen is faded, except status bar

I am now wondering how I can add the UIView() I created to the top position, so it goes over the status bar as well. I know it might be tricky, but I have seen applications where there is a black bar over the status bar, so I think this is what I need and then set the alpha to .5 accordingly.

What have I tried so far:

  • fadeBackground.window?.windowLevel = UIWindow.Level.statusBar + 1
  • fadeBackground.layer.zPosition = 1

But neither seem to work. I have also tried adding the UIView() to the keyWindow with UIApplication.shared.keyWindow?.addSubview(fadeBackground), but also without success. Any ideas or suggestions?

PennyWise
  • 595
  • 2
  • 12
  • 37

2 Answers2

2

You can add another subview just inside StatusBarView to make text inside also faded.

extension UIApplication {
    var statusBarView: UIView? {
        return value(forKey: "statusBar") as? UIView
    }
}

And then in ViewController:

class CustomTabBarController: UITabBarController {
    lazy var fadeStatusBarBackground: UIView = {
        let fadeBackground = UIView(frame: UIApplication.shared.statusBarView?.frame ?? .zero)
        fadeBackground.backgroundColor = UIColor.black
        fadeBackground.alpha = 0.5
        return fadeBackground
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        UIApplication.shared.statusBarView?.addSubview(fadeStatusBarBackground)
    }
}
Mateusz Tylman
  • 271
  • 1
  • 2
  • 17
  • This doesn't do the trick... I am working inside my UITabBarController class, which sets the UINavigationController like this: `let HomeController = UINavigationController(rootViewController: HomeViewController())` so I can't access it as you suggest – PennyWise Nov 28 '18 at 15:12
  • So as I understand you have UITabBarController with HomeController. at this point you want to present some custom ViewController that will have background faded above fullscreen? – Mateusz Tylman Nov 28 '18 at 15:18
  • That is correct. However I don't want the ViewController to have a faded background, I want to add a `UIView` with a faded background. Then, above that, I will present a ViewController which will not be faded but the background will be. However that is not the problem at this moment, the problem is the status bar not fading as I want it to. – PennyWise Nov 28 '18 at 15:20
  • I'm actually a bit confused because your code works for me. If I want to add fadeBackground inside UITabBarController as subview of main view it will cover everything including status bar – Mateusz Tylman Nov 28 '18 at 15:28
  • But does it also add the black color with .5 alpha to the text of the status bar? So does the green color of the battery indicator in the status bar also fade with .5 black color? – PennyWise Nov 28 '18 at 15:31
  • I have edited my post with answer that should work for you. It will also fade status bar text. Disadvantage of this answer is that you have to add another UIView just inside status bar – Mateusz Tylman Nov 28 '18 at 15:45
  • That's wonderful. Precisely what I was looking for. Added the fade for the status bar, then add another fade for the view. Set the frame of the fade for the view to a y-position equal to the statusBar height, so they don't overlap (otherwise the statusbar background gets faded twice). However, I had to change the alpha for the fade of the statusbar to .29 and the fade of the view to .5 for them to fade equally. Any idea why that is? - thank you very much for the help, much appreciated! – PennyWise Nov 28 '18 at 15:59
  • @PennyWise I think this is related to my previous comment - Your code works on status bar but it doesn't fade text. So status bar now has 2 views with fade on, one on background(your code) and one on text and background(my answer). You could change frame of your code to not cover status bar and it should work as expected – Mateusz Tylman Nov 28 '18 at 16:31
0

Try this, it will add an view over the entire screen including statusBar,

if let appDelegate = UIApplication.shared.delegate as? AppDelegate, let window = appDelegate.window {
        let windowFrame = window.frame
        let overlayView = UIView(frame: windowFrame)
        imageView.backgroundColor = UIColor.black.withAlphaComponent(0.7)
        window.addSubview(overlayView)
    }
Sumeet.Jain
  • 1,533
  • 9
  • 26
  • Tried this, but it does not add the view e.g. I can't see it. I tried printing something inside the closure and this works - so the if let statement is not the problem. – PennyWise Nov 28 '18 at 15:06