2009-08-12 10 views
7

Sto progettando un'applicazione Quiz semplice. L'applicazione deve visualizzare diversi tipi di QuizQuestions. Ogni tipo di QuizQuestion ha un comportamento e un'interfaccia utente distinti.Design subview iPhone (UIView vs UIViewController)

L'interfaccia utente sarà qualcosa di simile: alt text http://dl.getdropbox.com/u/907284/Picture%201.png

Mi piacerebbe essere in grado di progettare ogni tipo di QuizQuestion in Interface Builder.

Ad esempio, un MultipleChoiceQuizQuestion sarebbe simile a questa: alt text http://dl.getdropbox.com/u/907284/Picture%202.png

In origine, ho pensato di rendere la classe QuizQuestion un UIViewController. Tuttavia, ho letto nella documentazione di Apple che UIViewControllers dovrebbe essere utilizzato solo per visualizzare un'intera pagina.

Pertanto, ho creato il mio QuizController (che gestisce l'intero schermo, ad esempio i pulsanti prev/next) un UIViewController e la mia classe QuizQuestion una sottoclasse di UIView.

Tuttavia, per caricare questo UIView (creato nel IB), devo [1] effettuare le seguenti operazioni nel mio costruttore:

//MultipleQuizQuestion.m 
+(id)createInstance { 
    UIViewController *useless = [[UIViewController alloc] initWithNibName:@"MultipleQuizQuestion" bundle:nil]; 
    UIView *view = [[useless.view retain] autorelease]; 
    [useless release]; 
    return view; // probably has a memory leak or something 
} 

Questo tipo di accesso non sembra essere standard o object-oriented. Questo tipo di codice è normale/accettabile? O ho fatto una scelta sbagliata da qualche parte nel mio progetto?

Grazie,

di modifica (per chiarezza): Mi piacerebbe avere una classe separata per controllare il multipleChoiceView ... come un ViewController ma a quanto pare questo è solo per intere finestre. Forse dovrei creare MultipleChoiceViewManager (non controller!) E impostare il proprietario del file su quello?

risposta

5

Sei sulla strada giusta. Nel tuo xib di QuizController, puoi creare viste separate trascinandole nella finestra principale di xib piuttosto che nella vista principale del QuizController. Quindi puoi progettare ogni vista di cui hai bisogno in base ai tuoi tipi di domande. Quando l'utente tocca avanti o indietro, rimuovi la vista precedente e carica la vista necessaria in base al tipo di domanda usando -addSubview sulla vista principale del controller di visualizzazione e tiene traccia di quale visualizzazione secondaria è attualmente visualizzata. Cercando qualcosa di simile:

[currentView removeFromSuperView]; 

switch(questionType) 
{ 
    case kMultipleChoice: 
     [[self view] addSubview:multipleChoiceView]; 
     currentView = multipleChoiceView; 
     break; 
    case kOpenEnded: 
     [[self view] addSubview:openEndedView]; 
     currentView = openEndedView; 
     break; 
// etc. 
} 

Dove vista scelta multipla e openEndedView sono prese UIView nel QuizController collegato ai panorami che si progettato in IB. Potrebbe essere necessario fare confusione con la posizione della vista all'interno della vista genitore prima di aggiungerla per farla visualizzare nel posto giusto, ma puoi farlo con le chiamate a -setBounds/-setFrame e/o -setCenter su UIView .

+0

Grazie, ma mi piacerebbe avere una classe separata per controllare il multipleChoiceView ... come un ViewController ma apparentemente è solo per l'intera finestra. Forse dovrei creare MultipleChoiceViewManager (non controller!) E impostare il proprietario del file su quello? – tba

+0

Penso che tu stia rendendo più difficile per te farlo in quel modo. La delega è ciò che devi usare indipendentemente dal fatto che la tua decisione riguardi il punto in cui desideri inserire il codice, nella sua classe o nella classe del controller di visualizzazione in cui verrà utilizzato. Dipende ovviamente da te, ma non penso che stai guadagnando nulla mettendolo nella sua stessa classe. I migliori saluti. –

0

Sì, IB su iPhone vuole davvero che il proprietario di File sia una sottoclasse UIViewController, che rende ciò che si desidera un po 'complicato. Che cosa si può fare è caricare il pennino contro un'UIViewController esistente invece di istanziare una utilizzando il pennino:

@implementation QuizController 

- (void) loadCustomViewFromNib:(NSString *)viewNibName { 
    (void)[[NSBundle mainBundle] loadNibNamed:viewNibName owner:self options:nil]; 
} 

@end 

che farà sì che il runtime per caricare il pennino, ma invece di creare un nuovo controller al fine di collegare le azioni e punti vendita userà ciò che si trasferisce come proprietario. Dal momento che passiamo autonomamente nella vista definita in quel pennino sarà collegato a qualsiasi IBOutlet a cui è assegnato dopo la chiamata.

+0

Grazie è uno snippet utile – tba

Problemi correlati