El controller de vista modal no incluye la barra de estado

Estoy desarrollando una aplicación ios. Tengo una vista principal y en esta vista estoy tratando de presentar un controller de vista modal con background atenuado (negro con opacidad). El problema es que la barra de estado no se ve afectada por este color y permanece igual.

Así es como presento el controller de vista:

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 } 

Aquí hay algunas capturas de pantalla para demostrar el problema:

Este es el problema (color de la barra de estado): Ilustración del problema Esta es la vista modal en el guión gráfico: guión gráfico

No puedo reproducir su problema, el siguiente código funciona sin problemas en mi aplicación de vista única:

 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) 

Sin embargo, tenga en count que debería presentarse sobre el controller raíz de la vista. A veces puede get efectos extraños al presentar desde sus controlleres internos:

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

También asegúrese de que está utilizando el modalPresentationStyle correcto.

Ejemplo

este código funciona para mí, cuando UIViewController con alpha! = 1. presente UIViewController como:

 let storyBoard = UIStoryboard(name: "Main", bundle: nil) let destinationVC = storyBoard.instantiateViewController(withIdentifier: "AddComment") as! AddCommentViewController destinationVC.modalPresentationStyle = .overCurrentContext //this line is important destinationVC.delegate = self destinationVC.restId = self.restaurant.id self.present(destinationVC, animated: true, completion: nil) 

luego en el controller de vista de destinoVC

 override func viewWillDisappear(_: Bool) { UIView.animate(withDuration: 1, animations: { () in self.view.backgroundColor = .clear }) super.viewWillDisappear(true) } override func viewWillAppear(_: Bool) { UIView.animate(withDuration: 1, animations: { () in self.view.backgroundColor = UIColor.black.withAlphaComponent(0.5) }) super.viewWillAppear(true) } 

y establezca su backgroundColor en .clear en viewDidLoad o storyboard. Por UIViewController tanto, UIViewController cubre toda la pantalla, incluida la barra de estado.

Podría ser extremadamente práctico y simplemente esconder la barra de estado cuando el controller de vista modal está activado:

  override func prefersStatusBarHidden() -> Bool { return true } 

Esta es la solución que puede estar buscando:

 if let window = UIApplication.shanetworking.keyWindow { window.windowLevel = UIWindowLevelStatusBar + 1 } 

La idea principal detrás de este código es que la window de su aplicación tiene un nivel de window que es más bajo que el nivel de window de la barra de estado. Y lo que hace este código, simplemente coloque el nivel de la window de su window más alto que el nivel de la window de la barra de estado, y su window ahora puede cubrir la barra de estado. No olvide que este código debe ser llamado en el hilo principal, justo antes de presentar su controller de vista. ¡Buena suerte!

Las transiciones de animation personalizadas se deben realizar usando UIViewControllerAnimatedTransitioning . Aquí hay un tutorial para este propósito: https://www.raywenderlich.com/110536/custom-uiviewcontroller-transitions

Si lo único que deseas es una animation de desvanecimiento, puedes tenerla cambiando la propiedad modalTransitionStyle del viewController que vas a mostrar.

Trate de arreglar su código de esta manera:

 guard let shareViewController = self.storyboard?.instantiateViewControllerWithIdentifier("ShareViewController") as! ShareViewController else { //Fallback in case of nil? return } shareViewController.modalTransitionStyle = .crossDissolve presentViewController(shareViewController, animated: true, completion: nil) 

También tenga en count que presentViewController(shareViewController, animated: true, completion: nil) es para swift 2. present(shareViewController, animated: true, completion: nil) 3 equivalente estaría present(shareViewController, animated: true, completion: nil)

puede agregar este código para ver el controller para Swift 3 :

 let statusView: UIView = UIView(frame: CGRect(x: 0.0, y: -20.0, width: UIScreen.main.bounds.size.width, height: 20.0)) statusView.backgroundColor = UIColor.black statusView.alpha = 0.8 self.addSubview(self.statusView) 

Establezca su controller de vista como el controller de vista raíz de una UIWindow , luego presente la window en el nivel UIWindowLevelAlert .

A continuación se muestra una class Swift 3 utilizada para animar una window emergente modal sobre todos los demás elementos de la interfaz de usuario, incluida la barra de estado. Se utiliza una vista scrim para sombrear la interfaz de usuario de background e interceptar toca para descartar la vista.

 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 } ) } } 

Para presentar la vista:

 let modalView = ModalViewController() modalView.present() 

Para descartar la vista, toque en cualquier parte del scrim.