2016-02-18 9 views
11

Sto sviluppando un'applicazione ios. Ho una vista principale e in questa vista sto cercando di presentare un controller di visualizzazione modale con sfondo grigio (nero con opacità). Il problema è che la barra di stato non è influenzata da questo colore e rimane la stessa.Il controller della vista modale non copre la barra di stato

Questo è come mi presento il controller della 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 
      } 

Ecco alcuni screenshot per dimostrare il problema:

Questo è il problema (stato barra dei colori): Problem illustration Questo è il modal visualizza nello storyboard: storyboard

+0

qualche aiuto ragazzi ?? –

+0

si prega di condividere il codice di ShareViewController se ce ne sono in –

risposta

0

questo codice funziona per me, quando sto presentando UIViewController con alpha! = 1. presente UIViewController come:

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) 

poi destinationVC controller di vista

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

e impostare la backgroundColor a .clear in viewDidLoad o storyboard. Quindi UIViewController copre l'intero schermo, inclusa la barra di stato.

0

Potresti essere estremamente pratico e semplice nascondere la barra di stato quando il controller di vista modale è su:

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

Suppongo che questo * non * che cosa è l'OP cercando, non è di nascondere la barra di stato, il suo proposito di coprirlo. Ad ogni modo, potrebbe essere una soluzione ... –

+0

Ho trovato che arriva un punto in cui cercare la soluzione pura e bella non ne vale la pena, perché l'SDK di Apple è tutt'altro che puro e bello. – ClayJ

+0

In realtà, è solo che devi guardare oltre i tuoi limiti)) –

0

ecco la soluzione si potrebbe essere alla ricerca di:

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

L'idea principale dietro questo codice, window della tua applicazione ha un livello di finestra inferiore al livello della finestra della barra di stato. E ciò che fa questo codice, basta mettere il livello della finestra della finestra più in alto del livello della finestra della barra di stato e la finestra può ora coprire la barra di stato. Non dimenticare, questo codice deve essere richiamato sul thread principale, appena prima di presentare il tuo controller di visualizzazione. In bocca al lupo!

+0

Questo è piuttosto pericoloso. Cambiando il livello di 'keyWindow' puoi ottenere effetti molto strani quando mostri la tastiera (che si trova in una finestra separata). Inoltre, si dovrebbe ripristinare il livello originale quando si chiude. Vorrei consigliare di creare una nuova finestra, delle stesse dimensioni della barra di stato e metterla in cima alla barra di stato, nascondendola e mostrandola quando il controller appare e scompare. – Sulthan

+0

Le cose pericolose non sono pubbliche, come sappiamo. Sto solo postando la soluzione che produce l'effetto proprio come l'OP sta chiedendo. Naturalmente, le tue considerazioni sono giuste, se non usate con attenzione questo metodo potrebbe produrre qualche output indesiderato, ma potrei discutere con la tua opinione sulla tastiera. Comunque, senza offesa, le tue soluzioni sembrano migliori di così. Vorrei raccomandare all'OP di usare la tua soluzione. –

0

Le transizioni di animazione personalizzate devono essere eseguite utilizzando UIViewControllerAnimatedTransitioning. Ecco un tutorial per questo scopo: https://www.raywenderlich.com/110536/custom-uiviewcontroller-transitions

Se invece si è un'animazione dissolvenza si può avere modificando la proprietà modalTransitionStyle del viewController che si sta per visualizzare.

Prova fissando il codice in questo modo:

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) 

Inoltre si prega di notare che presentViewController(shareViewController, animated: true, completion: nil) è per una rapida 2. L'equivalente rapida 3 sarebbe present(shareViewController, animated: true, completion: nil)

5

non riesco a riprodurre il problema, le seguenti opere di codice senza problemi nella mia app a vista singola:

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) 

Tuttavia, è necessario presentare il controller di root del vista.A volte si può ottenere strani effetti in occasione della presentazione dei controller interni:

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

anche assicurarsi che si stia utilizzando il modalPresentationStyle.

Example

0

è possibile aggiungere questo codice per visualizzare controller per 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) 
0

Impostare il controller di vista come il controller di vista radice di un UIWindow, poi presenta la finestra al UIWindowLevelAlert livello.

Di seguito è una classe Swift 3 utilizzata per animare un popup modale su tutti gli altri elementi dell'interfaccia utente, inclusa la barra di stato. Una vista rigida viene utilizzata per ombreggiare l'interfaccia utente di sfondo e tocca l'interruzione per ignorare 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 
      } 
     ) 
    } 
} 

di presentare la vista:

let modalView = ModalViewController() 
modalView.present() 

Per chiudere la vista, toccare un punto qualsiasi della tela.