Размещение UIView для покрытия TabBar и NavBar

Я пытаюсь сделать всплывающее окно (UIView) с прозрачным фоном (еще UIView). Все работает нормально для «всплывающего окна UIView», но я не мог понять, как сделать «прозрачный фон UIView» (над панелью навигации и панелью вкладок).

Сначала я создал UIView в раскадровке и подключил розетку:

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

Затем при отображении popupView я создаю прозрачный фон 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)
 }

Однако фоновое представление не выходит за пределы NavigationBar или TabBar. Я пробовал это, но ничего не меняется:

myTabBar.view.bringSubviewToFront(opaqueView)

Чего я хочу добиться, так это того, чтобы, имея popup UIView в самом начале, иметь opaque UIView над всем, включая NavBar и TabBar, но позади popup UIView


Обновление:

Что касается ответа @Alex, с помощью этого фрагмента я добился отображения opaqueView поверх TabBar и NavBar; но теперь он также выходит за пределы 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) 
}

Как разместить opaqueView ниже popupView, а opaqueView выше всего остального?


person senty    schedule 31.05.2016    source источник


Ответы (6)


Попробуй это:

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

Обновление для Swift 4.2

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

Обновление для Swift 5

UIApplication.shared.keyWindow!.bringSubviewToFront(opaqueView!)
person Alex Kosyakov    schedule 31.05.2016
comment
Я тоже пробовал это, он переносит opaqueView поверх popupView (чего я не хочу) и не переносит его поверх NavBar и TabBar. К сожалению, ваш ответ не помогает :/ - person senty; 31.05.2016
comment
Чтобы это работало, вы должны добавить свой opaqueView следующим образом: UIApplication.sharedApplication().keyWindow!.addSubview(opaqueView); Тогда непрозрачный вид будет в верхней части ваших подвидов. Вы не можете добавить его в свой вид (self.view.addSubview(opaqueView)) и дождаться его отображения на панели навигации и панели вкладок. Одно из других решений — добавить его в tabbarController.view или navigationController.view. - person Alex Kosyakov; 31.05.2016
comment
Работает как шарм. Большое спасибо. Но у меня есть вопрос. Когда я использую UIApplication.sharedApplication().keyWindow!.addSubview(opaqueView);, opaqueView превосходит popUpView. Я пробовал использовать opaqueView.bringSubviewToFront(popupView), но ничего не меняется. Как я могу поставить «popUpView» выше «opaqueView»? - person senty; 31.05.2016
comment
Вы можете использовать методы insertSubview..belowSubview или insertSubview..aboveSubview, но в этом случае вы должны добавить свои подпредставления в одно и то же представление. - person Alex Kosyakov; 31.05.2016
comment
Сначала я попробовал UIApplication.sharedApplication().keyWindow!.addSubview(popupView). Это ничего не изменило. Затем, opaqueView.insertSubview(popupView, atIndex: 1), однако, это также делает popupView прозрачным (opaqueView 0.5 .alpha влияет на popupview). Я застрял :/ Что может быть решением? - person senty; 31.05.2016
comment
Также пробовал UIApplication.sharedApplication().keyWindow!.bringSubviewToFront(popupView), но это также удерживает opaqueView вверху - person senty; 31.05.2016
comment
UIApplication.sharedApplication().keyWindow!.addSubview(popupView) UIApplication.sharedApplication().keyWindow!.insertSubview(opaqueView нижеSubview: popupView) - person Alex Kosyakov; 31.05.2016
comment
Использование этого также вызывает opaqueView над popupView:/ - person senty; 31.05.2016
comment
Вы уверены, что не используете метод insert..aboveSubview? И я забыл написать, что вам не нужно вызывать функцию BringSubviewToFront. - person Alex Kosyakov; 31.05.2016
comment
Я запутался. Что мне написать конкретно? Не могли бы вы зайти в чат? Давайте продолжим этот разговор в чате. Это то, что я точно пытался UIApplication.sharedApplication().keyWindow!.insertSubview(opaqueView, belowSubview: popupView) - person senty; 31.05.2016
comment
Ответил вам в чате - person Alex Kosyakov; 31.05.2016

(swift 3+) Это сделает ваше представление поверх панели вкладок и панели навигации.

UIApplication.shared.keyWindow!.addSubview(yourView)
UIApplication.shared.keyWindow!.bringSubview(toFront: yourView)
person Daniel Raouf    schedule 21.05.2018

    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

              }
          }

предварительный просмотр результата

person Hackman    schedule 04.06.2017
comment
Привет, @Hackman, это отличный ответ! Как вы сможете применить UITapGesture к TransparentBackground, чтобы закрыть представление, точно так же, как кнопка OK, но вместо UITapGesture. Большое спасибо за ваш ответ - person juelizabeth; 02.07.2017
comment
Привет, @juelizabeth, хороший вопрос. Чтобы коснуться прозрачного представления, создайте UITapGestureRecognizer и добавьте его в метод addButtonTapped. Просто добавьте эти две строки в addButtonTapped let tap = UITapGestureRecognizer(target: self, action: #selector(FirstViewController.handleOKButtonTapped(_:))) self.transparentBackground.addGestureRecognizer(tap) - person Hackman; 05.07.2017
comment
Большое спасибо, это действительно помогло - person juelizabeth; 05.07.2017
comment
что такое прозрачный фон? приложение не позволит мне запуститься, потому что значение типа «ViewController» не имеет члена «transparentBackground» - person Saeed Rahmatolahi; 06.01.2018
comment
@SaeedRahmatolahi TransparentBackground — это свойство uiview. объявить внутри контроллера представления - person Hackman; 12.01.2018

Лучшее решение:

tabBarController?.view.addSubview(view)
person Daniel    schedule 05.02.2019

UIApplication.shared.keyWindow!.bringSubviewToFront(view: view) устарел после iOS 13. Лучший способ сделать так, чтобы ваше прозрачное представление покрывало как контроллер вкладок, так и контроллер навигации.

if let tabBarController = self.tabBarController {
    tabBarController.view.addSubview(view)
}
person F. Morales    schedule 22.03.2020

Вид, который вы хотите сделать прозрачным, используйте этот

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

person sumeet    schedule 06.06.2017