Placing UIView To Cover TabBar & NavBar
Asked Answered
C

6

17

I am trying to make a popup (UIView) with a transparent background (another UIView). Everything is working fine for the 'popup UIView' but I couldn't figure out how to bring 'transparent background UIView' (above NavigationBar and TabBar).

First I created the UIView in the Storyboard and connected the outlet:

popupView.center = CGPointMake(CGRectGetMidX(self.view.bounds), tableView.center.y);
self.view.addSubview(popupView)
popupView.clipsToBounds = true
popupView.alpha = 0

Then, while displaying popupView I am creating the transparent background UIView:

 func clicked() {
    self.popupView.alpha = 1

    let screenSize: CGRect = UIScreen.mainScreen().bounds
    let opaqueView = UIView()
    opaqueView.frame.size = CGSize(width: screenSize.width, height: screenSize.height)
    opaqueView.backgroundColor = UIColor.blackColor()
    opaqueView.alpha = 0.5

    self.view.addSubview(opaqueView)
 }

However, the background view doesn't get over NavigationBar or TabBar. I tried this but nothing changes:

myTabBar.view.bringSubviewToFront(opaqueView)

What I want to achieve is that, while having popup UIView at the very front, having opaque UIView over everything including NavBar and TabBar, but behind popup UIView


Update:

Regarding @Alex's answer, with this chunk, I achieved displaying opaqueView over TabBar & NavBar; but now it's also going above the popupView.

func display() {
   popupView.center = CGPointMake(CGRectGetMidX(self.view.bounds), tableView.center.y);
    self.view.addSubview(popupView)
    popupView.clipsToBounds = true

    let opaqueView = UIView()
    let screenSize: CGRect = UIScreen.mainScreen().bounds
    opaqueView.frame.size = CGSize(width: screenSize.width, height: screenSize.height)
    UIApplication.sharedApplication().keyWindow!.insertSubview(opaqueView, belowSubview: popupView) 
}

How can I place opaqueView below popupView while opaqueView is above everything else?

Cockchafer answered 31/5, 2016 at 18:6 Comment(0)
L
14

Try this:

UIApplication.sharedApplication().keyWindow!.bringSubviewToFront(opaqueView)

Updating for Swift 4.2

 UIApplication.shared.keyWindow!.bringSubview(toFront: opaqueView!)

Updating for Swift 5

UIApplication.shared.keyWindow!.bringSubviewToFront(opaqueView!)
Longer answered 31/5, 2016 at 18:18 Comment(11)
I tried this too, it's bringing the opaqueView over popupView (which I don't want), and doesn't bring it over NavBar and TabBar. Unfortunately, your answer doesn't help :/Cockchafer
To make it work you should add your opaqueView like this: UIApplication.sharedApplication().keyWindow!.addSubview(opaqueView); Then opaque view will be on the top of your subviews. You can't add it to your view (self.view.addSubview(opaqueView)) and wait for displaying it over navigation bar and tab bar. One of other solutions is to add it to tabbarController.view or navigationController.view.Longer
Works like charm. Thanks a lot. But I have a question. When I use UIApplication.sharedApplication().keyWindow!.addSubview(opaqueView); opaqueView gets over popUpView. I tried using opaqueView.bringSubviewToFront(popupView), but doesn't change anything. How can I bring 'popUpView' above 'opaqueView'?Cockchafer
You can use insertSubview..belowSubview or insertSubview..aboveSubview methods, but in this case you should add your subviews to the same view.Longer
First I tried UIApplication.sharedApplication().keyWindow!.addSubview(popupView). This didn't change anything. Then, opaqueView.insertSubview(popupView, atIndex: 1), however, it's also making the popupView transparent (opaqueView's 0.5 .alpha affects popupview). I am stuck :/ What can be the solution?Cockchafer
Also tried UIApplication.sharedApplication().keyWindow!.bringSubviewToFront(popupView) but this also keeps opaqueView at the topCockchafer
UIApplication.sharedApplication().keyWindow!.addSubview(popupView) UIApplication.sharedApplication().keyWindow!.insertSubview(opaqueView belowSubview: popupView)Longer
Using this causes opaqueView above popupView too :/Cockchafer
Are you sure you not using insert..aboveSubview method? And I forgot to write in this causes you don't need to call bringSubviewToFront functionLonger
I got confused. What should I write exactly? Can you please come to chatroom? Let's continue this conversation in chatroom.. This is what I exactly tried UIApplication.sharedApplication().keyWindow!.insertSubview(opaqueView, belowSubview: popupView)Cockchafer
Answered you in the chatroomLonger
B
8

UIApplication.shared.keyWindow!.bringSubviewToFront(view: view) was depreciated after iOS 13. The best way to have your transparent view cover both the tab controller and nav controller is by doing this.

if let tabBarController = self.tabBarController {
    tabBarController.view.addSubview(view)
}
Bernardinebernardo answered 22/3, 2020 at 6:9 Comment(0)
B
6

(swift 3+) This will make your view on top of tab bar and navigation bar

UIApplication.shared.keyWindow!.addSubview(yourView)
UIApplication.shared.keyWindow!.bringSubview(toFront: yourView)
Butternut answered 21/5, 2018 at 14:54 Comment(0)
T
5
    func addButtonTapped(){
              if self.transparentBackground == nil{
                  self.transparentBackground = UIView(frame: UIScreen.main.bounds)
                  self.transparentBackground.backgroundColor = UIColor(white: 0.0, alpha: 0.54)
                  UIApplication.shared.keyWindow!.addSubview(self.transparentBackground)
                  self.opaqueView = self.setupOpaqueView()
                  self.transparentBackground.addSubview(opaqueView)
                  UIApplication.shared.keyWindow!.bringSubview(toFront: self.transparentBackground)
                  self.view.bringSubview(toFront: transparentBackground)
              }
          }

          func setupOpaqueView() -> UIView{
                let mainView = UIView(frame: CGRect(x: 16, y: 100, width: Int(UIScreen.main.bounds.width-32), height: 200))
                mainView.backgroundColor = UIColor.white
                let titleLabel = UILabel(frame: CGRect(x: 16, y: 20, width: Int(mainView.frame.width-32), height: 100))
                titleLabel.text = "This is the opaque"
                titleLabel.textAlignment = .center
                titleLabel.font = font
                titleLabel.textColor = UIColor(white: 0.0, alpha: 0.54)
                mainView.addSubview(titleLabel)


                let  OKbutton = UIButton(frame: CGRect(x: 16, y: Int(mainView.frame.height-60), width: Int(mainView.frame.width-32), height: 45))
                OKbutton.backgroundColor = UIColor(red: 40.0 / 255.0, green: 187.0 / 255.0, blue: 187.0 / 255.0, alpha: 1)
                OKbutton.layer.cornerRadius = 10
                mainView.addSubview(OKbutton)
                OKbutton.setTitle("OK", for: .normal)
                OKbutton.setTitleColor(UIColor.white, for: .normal)
                OKbutton.titleLabel?.font = font
                OKbutton.addTarget(self, action:  #selector(FirstViewController.handleOKButtonTapped(_:)), for: .touchUpInside)

                return mainView

          }

          func handleOKButtonTapped(_ sender: UIButton){
              UIView.animate(withDuration: 0.3, animations: {
                  self.transparentBackground.alpha = 0
              }) { done in
                  self.transparentBackground.removeFromSuperview()
                  self.transparentBackground = nil

              }
          }

preview of the result

Tristram answered 4/6, 2017 at 7:30 Comment(5)
Hey @Tristram this is a great answer! How will you be able to apply a UITapGesture to the transparentBackground to dismiss the view, just the same like the OK button does but instead a UITapGesture. Thank you so much for your responseEffloresce
Hey @juelizabeth, good question. To have the tap on the transparent view, create a UITapGestureRecognizer and add it to the addButtonTapped method. Just add these two lines to the addButtonTapped let tap = UITapGestureRecognizer(target: self, action: #selector(FirstViewController.handleOKButtonTapped(_:))) self.transparentBackground.addGestureRecognizer(tap)Tristram
Thank you very much, this really helpedEffloresce
what is transparentBackground? the app won't let me to run because the Value of type 'ViewController' has no member 'transparentBackground'Manvil
@SaeedRahmatolahi the transparentBackground is a uiview property. declare inside the view controllerTristram
C
5

Best solution is:

tabBarController?.view.addSubview(view)
Courser answered 5/2, 2019 at 18:15 Comment(0)
E
-2

The view which you want to do transparent, use this

yourView.backgroundColor = UIColor.black.withAlphaComponent(0.7)

Everett answered 6/6, 2017 at 10:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.