Domanda

Ho riscontrato un comportamento strano e vorrei che mi venisse spiegato quale affermazione sto facendo è sbagliata.

In una classe AppDelegate di un progetto WindowBased appena creato, sto aggiungendo un UIViewController alla finestra.
Posso farlo in due modi diversi:
- con un IBOutlet.In IB, ho semplicemente istanziato un UIViewController, impostato la sua classe su TestViewController e collegato (scenario A del codice).
- creazione dell'UIViewController con codice (scenario B).

    - (void)applicationDidFinishLaunching:(UIApplication *)application {    

#define USE_IBOUTLET YES // Comment this line to switch to scenario B

#ifdef USE_IBOUTLET
    // Scenario A

    [window addSubview:theTestViewController.view];
    [window makeKeyAndVisible];
#endif


#ifndef USE_IBOUTLET
    // Scenario B

    TestViewController *theTestViewControllerProgrammatically;

    theTestViewControllerProgrammatically = [[TestViewController alloc] initWithNibName:nil bundle:nil];

    // According to Apple: "It is a good idea to set the view's frame before adding it to a window.", so let's do it
    [theTestViewControllerProgrammatically.view setFrame:[[UIScreen mainScreen] applicationFrame]];

    [window addSubview:theTestViewControllerProgrammatically.view];

    [window makeKeyAndVisible];
#endif
}

Poiché non ho effettuato alcuna personalizzazione dell'oggetto in IB, dovrei avere lo stesso comportamento in entrambi gli scenari.

Lo scenario A, utilizzando IBOutlet, funziona come previsto.
Ma lo scenario B presenta i seguenti problemi:
- La vista non è nella posizione corretta (20 pixel in alto e coperta dalla barra di stato).
- La visualizzazione non viene ridimensionata correttamente (ad esempio, prova ad attivare la barra di stato della chiamata in corso)

Perché?

Archivio zip del progetto qui se vuoi riprodurre il problema: http://dl.dropbox.com/u/1899122/code/ProtoWindowBasedStrangeness.zip

È stato utile?

Soluzione

Si tratta di andare a suonare davvero sciocco dopo le mie risposte prolisso, ma il problema che stai avendo è semplice da risolvere (programatically).

Questa riga:

[theTestViewController.view setFrame:[[UIScreen mainScreen] applicationFrame]];

Dovrebbe in realtà essere:

[theTestViewControllerProgrammaticaly setFrame:[[UIScreen mainScreen] applicationFrame]];

Si stavano mettendo la cornice per il VC impostato da IB, non per quello che si è creato programatically.

In ogni caso - vale la pena notare che tutti i miei commenti valgono ancora! Ci sono ancora alcune cose che dovrete fare a livello di codice, se non si utilizza oggetti controller di IB (per esempio, la creazione di elementi della barra di navigazione)

Paul

Altri suggerimenti

Ho riscontrato un problema molto simile al tuo in quanto ho notato che gli oggetti VC non sono tutti uguali!Il problema che sto riscontrando è l'impostazione degli elementi della barra di navigazione, semplicemente non riesco a farlo quando il proprietario del file è un oggetto controller di visualizzazione di cui creo un'istanza a livello di codice.Funziona solo se annullo l'archiviazione degli oggetti controller di IB.

Ho scaricato il tuo progetto e ci ho giocato un po', e questo mi ha fatto riflettere ancora un po' su cosa potrebbe succedere.Penso di poter fornire una risposta ragionevole, ma non sono sicuro che esista una soluzione semplice...

Quello che credo stia succedendo è che Apple abbia creato questi oggetti controller in IB che sono leggermente più specializzati.Un suggerimento che ciò potrebbe essere vero è che gli oggetti IB VC hanno un attributo che puoi impostare che non ha una proprietà corrispondente diretta per una classe UIViewController che posso vedere, quindi gli oggetti controller di IB potrebbero avere alcune funzionalità aggiuntive che le sottoclassi non IB UIViewController non possono approfittare di.Dato che gli oggetti in un file .xib sono oggetti 'liofilizzati' completi, Apple potrebbe aver incluso tutti i tipi di attributi privati ​​che non possiamo vedere o utilizzare nelle loro versioni IB: questo potrebbe avere qualche effetto sul modo in cui gli oggetti vengono inizializzati .

Ad esempio, nel tuo MainWindow.xib, seleziona l'oggetto IB VC e puoi impostarne gli attributi dalla tavolozza Ispettore, come "Ridimensiona vista da NIB".Se deselezioni questa opzione ed esegui nuovamente l'app, vedrai il VC apparire esattamente come nello scenario B.Poiché non puoi controllare questo elemento dagli attributi del proprietario del file (anche se è come UIViewController), non puoi sfruttare qualsiasi cosa venga eseguita dal controller di visualizzazione per darti il ​​comportamento desiderato.

Il risultato di ciò è che quando si utilizza TestViewController.xib per inizializzare il tuo oggetto VC nel codice, nessuno degli attributi specifici IB di un VC è impostato, quindi viene creato un UIViewController standard e quindi cose come l'attributo "Ridimensiona vista da NIB" e l'impostazione degli elementi di navigazione devono essere implementato te stesso.

Non ho ancora trovato un modo per sfruttare le funzionalità dei controller di visualizzazione di IB quando ne creo un'istanza utilizzando initWithNibName:bundle:nibBundle (Immagino che siano tutte cose private a cui non possiamo accedere), ma spero che questo possa averti dato un punto di partenza...

Naturalmente potrei sbagliarmi completamente e qualcuno mi farà passare per un completo idiota!

Paolo

Probabilmente nel caso B quella vista non è a conoscenza della presenza di una barra di stato. È necessario ridimensionare di conseguenza e regolarne la posizione per prendere la barra di stato in considerazione. Questo viene fatto modificando il telaio (dimensioni) e limiti (posizione) proprietà di un UIView.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top