1

I know there have been some questions posted about this, but none have helped me with my specific issue. I would like to display a custom modal above the entire screen, but I would like to keep the Apple status bar visible. For the modal, I am using one UIView for the dimming effect and another for the actual view that the user would interact with. The entire modal is then added as a subview to the current view and brought to the front. Essentially, I am trying to replicate the behavior of the UIAlertView, except with a custom view. Here is some of my code:

var modalView:UIView = UIView(frame: self.view.window!.bounds)
modalView.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.66)
modalView.addSubview(customView)    

self.view.window!.addSubview(modalView)
modalView.window!.windowLevel = UIWindowLevelStatusBar + 1

self.bringSubviewToFront(modalView)

Above, customView is the UIView that the user interacts with.

This works great, but for some reason, the text on the Apple status bar just simply disappears even though the style of the status bar is set to LightContent. As can be seen in the code, I do not touch the status bar.

I am trying to get the text on the status bar to dim just like the rest of the screen and am currently stuck. Does anyone have any insight on how I can get the desired behavior?

Any help would be greatly appreciated!

Alexander
  • 3,959
  • 2
  • 31
  • 58
  • 1
    You could try going one level up and implementing your mechanism inside a new UIWindow. Here are some of the caveats to that approach: http://stackoverflow.com/q/8232398/1442620 – Anna Dickinson Nov 06 '14 at 14:38

2 Answers2

7

Updated Dec. 2017 • Swift 4 • iOS 10.0+

I briefly tried the accepted answer's edited solution, but I couldn't easily make an entire viewController for just a UIView banner. However, by accessing the statusBar value in UIApplication, I was able to add a UIView as a subview to statusBarView. This will put the UIView on top of the status bar. As far as I know, this is a relatively stable workaround that has worked for the last few iOS versions.

extension UIApplication {

    /// Returns the status bar UIView
    var statusBarView: UIView? {
        return value(forKey: "statusBar") as? UIView
    }

}

Usage

let customBannerView = CustomStatusView(with: message)
UIApplication.shared.statusBarView?.addSubview(customBannerView)
Matthew Barker
  • 638
  • 9
  • 13
  • I do not think this would be a good approach, since you are trying to access a private view that you shouldn't have access to. This approach works good in iOS 11, but not in iOS 9 for example, where you have to access to statusBarWindow before accessing statusBarView. I wouldn't do in this way. – Andrea Mario Lufino May 01 '18 at 07:40
5

EDIT (November 16, 2015)

I am copying my answer from this thread below:

This answer breaks in iOS 8.3+ and possibly previous versions of iOS 8. I DO NOT recommend that anyone uses it, especially since it is not guaranteed to work in future iOS versions.

My new solution uses the standard presentViewController method of a UIViewController. I initialize a UIViewController, add my custom modal View as a subview of the UIViewController, and then optionally position the modal View using constraints. Works like a charm!


Original Answer

Following Anna's advice, I got it working by using a UIWindow instead of a UIView. Here's my new code:

var modalWindow:UIWindow = UIWindow(frame: self.view.window!.bounds)

modalWindow.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.66)
modalWindow.hidden = false
modalWindow.windowLevel = (UIWindowLevelStatusBar + 1)

modalWindow.addSubview(customView)    

modalWindow.makeKeyAndVisible()

It now works exactly as before, except the text on the Apple status bar gets dimmed as well. Thank you very much for all of the help!

Community
  • 1
  • 1
Alexander
  • 3,959
  • 2
  • 31
  • 58
  • Just a quick note: to hide the window, set `modalWindow` to `nil`, like so: `modalWindow = nil` – Alexander Nov 07 '14 at 13:49
  • did you manage to handle the rotation for this temporary uiwindow? please check my question http://stackoverflow.com/questions/26976494/ios-8-7-uiwindow-with-uiwindowlevelstatusbar-rotation-issue – Hashmat Khalil Nov 18 '14 at 07:54
  • 1
    Hi @žhecownyakh, I would not recommend this solution going forward, even though it can work in iOS 9. The problem with using `UIWindow`s for modals is that they work differently in different versions of iOS. In some versions, they are in portrait mode only, and in others, they aren't. This makes this solution unpredictable and susceptible to breaking in the future. I would recommend my new answer here, using standard APIs: http://stackoverflow.com/questions/26916009/ios-8-uiwindow-orientation-is-always-portrait/27256489#27256489 – Alexander Nov 17 '15 at 00:54