Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modal view controller does not cover status bar

I'm developing an ios app. I have a a main view and in this view im trying to present a modal view controller with dimmed background(black with opacity). The problem is that the status bar is not affected by this color and remains the same.

This is how i present the view controller:

let shareViewController = self.storyboard?.instantiateViewControllerWithIdentifier("ShareViewController") as! ShareViewController
            shareViewController.battle = battle
            shareViewController.delegate = self
            let animation = CATransition()
            animation.duration = 1
            animation.type = kCATransitionFade
            self.view.window?.layer.addAnimation(animation, forKey: kCATransition)
            presentViewController(shareViewController, animated: false) {
               () in 
               // nothing here
            }

Here are some screenshots to demonstrate the problem:

This is the problem(status bar color): Problem illustration This is the modal view in storyboard: storyboard

like image 911
Eden.F Avatar asked Feb 18 '16 20:02

Eden.F


2 Answers

I cannot reproduce your problem, the following code works without problems in my single view app:

let viewController = UIViewController()
viewController.modalPresentationStyle = .overFullScreen
viewController.view.backgroundColor = UIColor.black.withAlphaComponent(0.5)

let animation = CATransition()
animation.duration = 1
animation.type = kCATransitionFade
self.view.window?.layer.add(animation, forKey: kCATransition)

self.present(viewController, animated: false, completion: nil)

However note that you should be presenting over the root controller of the view. Sometimes you can get strange effects when presenting from your internal controllers:

self.view.window?.rootViewController?.present(viewController, animated: false, completion: nil)

Also make sure you are using the correct modalPresentationStyle.

Example

like image 99
Sulthan Avatar answered Nov 17 '22 13:11

Sulthan


Set your view controller as the root view controller of a UIWindow, then present the window at the UIWindowLevelAlert level.

Below is a Swift 3 class used to animate a modal popup over all other UI elements, including the status bar. A scrim view is used to shade background UI and intercept touches to dismiss the view.

import UIKit

class ModalViewController: UIViewController {

    private let scrimView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = UIColor.black
        view.alpha = 0.0
        return view
    }()

    private var myWindow: UIWindow?

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.clear

        // Setup scrim View
        view.addSubview(scrimView)
        view.topAnchor.constraint(equalTo: scrimView.topAnchor).isActive = true
        view.leftAnchor.constraint(equalTo: scrimView.leftAnchor).isActive = true
        view.rightAnchor.constraint(equalTo: scrimView.rightAnchor).isActive = true
        view.bottomAnchor.constraint(equalTo: scrimView.bottomAnchor).isActive = true

        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismiss as (Void) -> Void))
        scrimView.addGestureRecognizer(tapGestureRecognizer)

        // Layout custom popups or action sheets
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        UIView.animate(withDuration: 0.25) {
            self.scrimView.alpha = 0.5
            // Animate in custom popups or action sheets
        }
    }

    func present() {
        myWindow = UIWindow(frame: UIScreen.main.bounds)
        myWindow?.windowLevel = UIWindowLevelAlert
        myWindow?.backgroundColor = UIColor.clear
        myWindow?.rootViewController = self
        myWindow?.isHidden = false
    }

    func dismiss() {

        UIView.animate(
            withDuration: 0.25,
            animations: {
                self.scrimView.alpha = 0.0
                // Animate out custom popups or action sheets
            },
            completion: { success in
                self.myWindow = nil
            }
        )
    }
}

To present the view:

let modalView = ModalViewController()
modalView.present()

To dismiss the view, tap anywhere on the scrim.

like image 23
Alex Avatar answered Nov 17 '22 13:11

Alex