2013-04-24 26 views
14

Dato il codice qui sottoCosa succede sotto il cofano quando presentiamoViewController?

self.view.backgroundColor = [UIColor yellowColor]; 
MyViewController *myVC = [[MyViewController alloc] initWithNibName:@"MyView" bundle:nil] 
myVC.view.backgroundColor = [UIColor clearColor]; 
myVC.modalPresentationStyle = UIModalPresentationFullScreen; 
[self presentViewController:myVC animated:NO completion:nil]; 

Cosa accade sotto il cofano quando chiamiamo presentViewController? Quando myVC è visibile non riesco a vedere il colore giallo, quindi ho controllato myVC.view.superView nel suo metodo viewDidAppear ed è UIWindow.

Q1. Significa che fino a quando la finestra modale non è in su presentandoViewController.view (self.view nel caso precedente) viene rimosso dalla gerarchia View e presentatoViewController.view (myVC.view nel caso precedente) viene aggiunto su UIWindow?

Q2. Cosa succederà se myVC.modalPresentationStyle! = UIModalPresentationFullScreen?

Q3. iOS rimuove anche tutte le viste da UIWindow tranne PresentationController.view finché non viene visualizzata la finestra di dialogo modale a schermo intero per l'ottimizzazione? Se NO, perché no?

+0

Che cos'è 'clippingVC'? – rptwsthi

risposta

18

In primo luogo, discutiamo il caso senza animazione.

Prima di chiamare present:

  1. La finestra è una gerarchia di vista, a partire dalla sua rootViewController vista.

Dopo aver chiamato present:

  1. La gerarchia vista esiste ancora senza modifiche.
  2. Alla finestra viene aggiunta una vista speciale a schermo intero denominata "visualizzazione dimming" (cioè non all'interno della vista di rootViewController ma all'interno della finestra (anche la finestra è UIView). Questa vista è trasparente, attenua la vista presentando controler e blocca l'interazione dell'utente.
  3. l'(modale) vista presentato del controller viene poi aggiunta anche alla finestra.

ci sono alcune altre viste aggiunte nella tra la finestra e la finestra del controller presentato. Se si accede la tua gerarchia di vista, vedrai le classi denominate _ControllerWrapperView o qualcosa di simile.Tuttavia, questo è cambiato tra le versioni di iOS e non dovresti fare affidamento sulla vista struttura. Si noti che il controller modale non può mai essere trasparente perché non è una vista secondaria diretta della finestra e i wrapper tra il controller e la finestra non sono trasparenti.

La custodia animata è quasi la stessa. Solo ci sono alcune animazioni fantasiose tra i passaggi.

Modifica 2: La risposta è stata davvero un po 'errata. C'è una grande differenza tra i controller presentati da iPhone e iPad.

Su iPhone, i controller presentati vengono sempre visualizzati a schermo intero ei controller presentati vengono effettivamente rimossi dalla finestra.

Su iPad, se il controller presentato non è a schermo intero (vedere UIModalPresentationStyle), il controller di presentazione rimane nella finestra.

vostre questioni:

è che media fino a quando la finestra modale è fino presentingViewController.view (self.view nel caso di cui sopra) viene rimosso dalla gerarchia View e presentedViewController.view (myVC.view nel caso di cui sopra) viene aggiunto su UIWindow?

Se il controller è a schermo intero, questa richiesta è vera. In caso contrario, il controller della vista di presentazione rimane lì, ma l'intero contenuto viene sovrapposto ad altre viste (anche se sono semi-trasparenti). Inoltre, ci sono sempre alcune viste tra le viste del controller presentato e di presentazione.

Che cosa succede se myVC.modalPresentationStyle! = UIModalPresentationFullScreen?

Vedere la risposta alla domanda precedente - su iPhone, non ci sarebbero differenze.

iOS rimuove anche tutte le viste da UIWindow tranne PresentationController.view fino a quando non viene visualizzata la finestra di dialogo modale a schermo intero per l'ottimizzazione? Se NO, perché no?

Dai miei test, solo il controller di presentazione viene rimosso dalla gerarchia delle finestre. Questo è probabilmente per ottimizzare le prestazioni del disegno. Questo è l'unico controller che il sistema può rimuovere in sicurezza. La rimozione di qualsiasi altra vista potrebbe causare problemi (ad esempio viste che dovrebbero essere sempre visibili).

Edit: Se si vuole fare un controller trasparente, è possibile:

  1. Aggiungere la vista direttamente alla visualizzazione della gerarchia (o alla visualizzazione del controller o alla finestra) con un'animazione di transizione (+[UIView transition...])
  2. Lo stesso ma anche l'aggiunta di un controller figlio al controller.
+2

Questa risposta è alquanto errata. Quando viene presentato un controller modale a schermo intero, UIKit rimuove le viste di altri controllori dalla finestra. In effetti, l'aggiunta/rimozione dalla finestra è esattamente ciò che appare '-viewDid/Will (Dis):' i metodi stanno segnalando. Ma Uikit li aggiunge alla finestra prima di tornare da loro. –

+1

@ BJHomer Avevi ragione. Ho per lo più esperienza di iPad quindi mi sono sbagliato nei casi di iPhone. Risolta la risposta. – Sulthan

+0

Questo è anche dai miei esperimenti -> "solo il controller che presenta viene rimosso dalla gerarchia della finestra". Spero che iOS non possa mai rimuovere tutte le altre viste dalla gerarchia delle finestre. @BJ Homer ha torto affermando che "Quando viene presentato un controller modale a schermo intero, UIKit rimuove le viste degli altri controllori dalla finestra." – msk

Problemi correlati