2010-03-11 22 views
18

Sto cercando di avvolgere la mia mente attorno ai controller in Cocoa Touch. Il problema principale è che mi piacerebbe avere più di un controller "sullo schermo" in una volta: voglio avere una vista ampia (con il controller A) composta da viste più piccole controllate dai propri controllori (per esempio B). Mi piacerebbe averlo in questo modo perché la divisione rende il codice molto più pulito. Ciò che è male è che i controller aggiuntivi (di tipo B) non sono "cittadini di prima classe" sullo schermo, ad esempio non ricevono le query di autorotazione e le notifiche. (E non è possibile visualizzare facilmente i controller modali, devono inviare il messaggio presentModal… al loro controller padre.)Più controller di visualizzazione sullo schermo contemporaneamente?

Qual è la differenza tra i controller A e B dal punto di vista Cocoa? Il sistema mantiene una sorta di puntatore al "frontmost controller", un privilegiato a cui invia notifiche e cose del genere? Perché gli altri controller non li ricevono, anche se le loro visualizzazioni sono sullo schermo? Avere più controller "sullo schermo" è considerato un hack? O è supportato e mi manca un punto? Grazie.


Ulteriori informazioni sul problema che sto cercando di risolvere: sto scrivendo un semplice browser di foto. Le foto vengono visualizzate a schermo intero, l'utente può scorrere verso sinistra o destra per cambiare foto. Il controller A si occupa della parte a scorrimento e i controller B si prendono cura di ogni foto stessa.

L'isolamento di B sembrava una buona idea, dal momento che le foto sono caricate dalla rete e ci sono molte cose che possono accadere, come la rete potrebbe essere inattiva eccetera. Nel controller B il codice è abbastanza semplice, poiché B funziona solo con una foto particolare. Se avessi spostato il codice sul controller A, le cose sarebbero diventate disordinate.

L'unica cosa che non mi piace della soluzione corrente è che devo lavorare manualmente attorno a B non essendo un controller di "prima classe". Devo passare alcune chiamate manualmente da A a B e quando B vuole visualizzare una finestra di dialogo modale, deve inviare il presentModal… a A. Che è brutto.

risposta

7

In primo luogo, e questo è importante, vista controllori non ottengono "sullo schermo" - vista DO. Il tuo controller di "livello superiore" può certamente trasmettere i tipi di messaggi che stai descrivendo ai suoi "sub-view-controller". In effetti, questo è il modo in cui la maggior parte delle app funziona. Prendi in considerazione un'app dotata di una barra delle schede e in cui le visualizzazioni utilizzano i controller di navigazione. In effetti, sono in esecuzione più registri di visualizzazione contemporaneamente, ciascuno con la propria vista sullo schermo in una volta: il controller di visualizzazione "root" sarà un'istanza (o sottoclasse) di UITabBarController, che quindi ha diversi UINavigationControllers nidificati, ciascuno che visualizzerà i controller di visualizzazione nidificati (come un'istanza o una sottoclasse di UITableViewController).

Si potrebbe leggere un po 'su come funziona responder chains. Considera un evento di tocco. Verrà generato per la vista più vicina alla cima dello stack, che può ricevere eventi, che si trova anche al di sotto del tocco. Se quella vista non può gestirlo, viene passata alla catena alimentare della gerarchia della vista fino a quando qualcosa non la gestisce (e poi la mangia).

Per quanto riguarda le specifiche della tua domanda, nel complesso, non sono sicuro di quale sia esattamente la strategia che descrivi che sta facendo per avvantaggiarti in termini di complessità. Dipende da come esattamente stai implementando le cose, ma avere dei controller di vista separati per ogni piccola sottoview potrebbe richiedere più codice di contabilità che avere solo un controller di visualizzazione che conosca tutti i suoi componenti di visualizzazione secondaria.

+0

Buona risposta, grazie.So che le visualizzazioni vengono visualizzate sullo schermo, non sui controller, ecco perché continuavo a scrivere "sullo schermo" tra virgolette, che significava "avere la sua vista sullo schermo". Scriverò di più sulla situazione nella domanda. – zoul

12

Non è strettamente correlato alla domanda originale ma importante.Apple afferma chiaramente in View Controller Programming Guide che un controller di visualizzazione è responsabile del controllo di esattamente il contenuto di uno schermo:

"Ogni oggetto di controllo di visualizzazione personalizzato creato è responsabile della gestione di esattamente il valore di una schermata di contenuto. la corrispondenza tra un controller di visualizzazione e uno schermo è una considerazione molto importante nella progettazione della tua applicazione.Non devi utilizzare più controller di visualizzazione personalizzati per gestire porzioni diverse della stessa schermata.Altrimenti, non devi utilizzare un singolo oggetto di controllo di visualizzazione personalizzato per gestire più schermate di contenuto.

Nota: se si desidera dividere uno schermo singolo in più aree e gestirne singolarmente separatamente, utilizzare oggetti controller generici (oggetti personalizzati de scendendo da NSObject) invece di visualizzare oggetti controller per gestire ciascuna sottosezione dello schermo. Quindi utilizzare un oggetto controller vista singola per gestire gli oggetti controller generici. Il controller della vista coordina le interazioni complessive dello schermo, ma inoltra i messaggi come necessario per gli oggetti controller generica gestisce "

Tuttavia nella Guida iPad programmazione dicono anche che ci possono essere vista contenitore Controller:

". Un controller della vista è responsabile per una vista unica. La maggior parte delle volte, è previsto che la vista di un controller di visualizzazione riempia l'intero intervallo della finestra dell'applicazione. In alcuni casi, tuttavia, un controller di visualizzazione può essere incorporato in un altro controller di visualizzazione (noto come controller di visualizzazione contenitore) e presentato insieme ad altri contenuti. I controller di navigazione e barra delle schede sono esempi di controller di visualizzazione contenitori. "

Fino a quanto non sapessi, non utilizzerei controller di sottoview in un controller di visualizzazione ma provo a sottoclasse NSObject e invierò loro messaggi dal mio controller di visualizzazione principale.

controllare anche questa discussione: MGSplitViewController discussion

+1

Il problema è come passare un messaggio dall'oggetto controller NSObject generico al View Controller. Avresti bisogno di entrambi i delegati o NSNotifications che è un dolore. – mskw

5

realtà è possibile farlo funzionare prima di iOS 5, da allora. molti di noi sono ta rgeting 4.xe 5.x allo stesso tempo. Ho creato una soluzione che funziona in entrambi, e funziona benissimo, poche app in uso nell'appstore :) Leggi my article about this o solo download and use a simple class che ho creato per questo scopo.

+0

È considerata una cattiva pratica da parte di Apple fare ciò prima di iOS5 (cioè prima che avessimo il contiguo fornito da Apple). Gli ingegneri Apple me l'hanno detto di persona. – ader

+0

Ho usato questa soluzione da più di un anno e non ho mai avuto problemi con questo. Il problema è che la maggior parte delle implementazioni che ho visto non si sono occupate della corretta gestione della memoria e di tutti i metodi importanti, e il mio lo gestisce correttamente. Per quanto mi piaccia il contenimento del controller di apple view dovrebbe essere introdotto con il rilascio di iPad, in quanto questo è lo scenario più comune per i controller di più viste. Anche questa è una soluzione approvata in molte app in appstore. Questa soluzione consente di riutilizzare i controller di visualizzazione iPhone senza problemi o mal di testa. –

4

Questa è una domanda piuttosto vecchia, ma poiché immagino ci siano persone che potrebbero affrontare lo stesso problema oggi vorrei condividere la mia soluzione. Stavo scrivendo questa applicazione che aveva questa schermata con un sacco di informazioni, paginazione, controlli ecc. Poiché secondo MVC documentation di Apple sul ruolo di ViewControllers, non dovresti implementare la logica in vista stessa, o accedere direttamente al modello di dati da esso, ho dovuto scegliere tra avere un Massive ViewController con poche migliaia di righe di codice che era sia difficile da mantenere e eseguire il debug (anche con i test di unità) o trovare un nuovo modo.

La mia soluzione era quella di utilizzare UIContainerView come di seguito: enter image description here

in questo modo, è possibile implementare la logica di ogni parte in un suo ViewController, e il controller della vista genitore si prende cura di vincoli e dimensionamento dei punti di vista.

Nota: Questa risposta è solo una guida per indicare la strada, è possibile trovare una spiegazione buona e dettagliate su come funziona e come implementarlo HERE

Problemi correlati