2009-08-12 19 views
7

Ich entwerfe eine einfache Quiz-Anwendung. Die Anwendung muss verschiedene Arten von QuizQuestions anzeigen. Jede Art von QuizQuestion hat ein unterschiedliches Verhalten und eine eigene Benutzeroberfläche.iPhone Subview Design (UIView vs UIViewController)

Die Benutzeroberfläche wird in etwa so sein: alt text http://dl.getdropbox.com/u/907284/Picture%201.png

Ich mag wäre in der Lage sein, jede Art von QuizQuestion im Interface Builder zu entwerfen.

Zum Beispiel kann ein MultipleChoiceQuizQuestion würde wie folgt aussehen: alt text http://dl.getdropbox.com/u/907284/Picture%202.png

Ursprünglich habe ich die QuizQuestion Klasse ein UIViewController machen geplant. Ich habe jedoch in der Apple-Dokumentation gelesen, dass UIViewControllers nur zum Anzeigen einer ganzen Seite verwendet werden sollte.

Daher habe ich meine QuizController (die den gesamten Bildschirm, z. B. Prev/Next-Schaltflächen verwaltet) eine UIViewController und meine QuizQuestion-Klasse eine Unterklasse von UIView.

jedoch diese UIView zu laden (in IB erstellt), muss ich [1] gehen Sie wie folgt in meinem Konstruktor:

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

Diese Art des Zugriffs scheint nicht Standard zu sein oder objektorientiert. Ist diese Art von Code normal/akzeptabel? Oder habe ich irgendwo in meinem Design eine schlechte Wahl getroffen?

Thankyou,

bearbeiten (für Klarheit): würde Ich mag eine eigene Klasse haben die multipleChoiceView zu steuern ... wie ein Viewcontroller aber anscheinend das ist nur für ganze Fenster. Vielleicht sollte ich einen MultipleChoiceViewManager machen (nicht Controller!) Und stattdessen den Besitzer der Datei festlegen?

Antwort

5

Sie sind auf dem richtigen Weg. In Ihrem QuizController xib können Sie separate Ansichten erstellen, indem Sie sie in das Hauptfenster des xib und nicht in die Hauptansicht des QuizControllers ziehen. Dann können Sie jede Ansicht, die Sie benötigen, entsprechend Ihren Fragetypen gestalten. Wenn der Benutzer auf "Weiter" oder "Zurück" klickt, entfernen Sie die vorherige Ansicht und laden Sie die gewünschte Ansicht basierend auf Ihrem Fragentyp mithilfe von -addSubview in der Hauptansicht des Ansichtscontrollers und verfolgen Sie, welche Teilansicht gerade angezeigt wird. Der Versuch, so etwas wie diese:

[currentView removeFromSuperView]; 

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

Wo Multiple-Choice-Ansicht und openEndedView sind UIView Stellen in Ihrem QuizController die Ansichten verbunden Sie in IB entworfen. Möglicherweise müssen Sie sich mit der Position Ihrer Ansicht in der übergeordneten Ansicht befassen, bevor Sie sie hinzufügen, damit sie an der richtigen Stelle angezeigt wird. Sie können dies jedoch mit Aufrufen von -setBounds/-setFrame und/oder -setCenter in der UIView tun .

+0

Danke, aber ich würde gerne eine separate Klasse haben, um die multipleChoiceView zu steuern ... wie ein ViewController, aber anscheinend ist das nur für ganze Fenster. Vielleicht sollte ich einen MultipleChoiceViewManager machen (nicht Controller!) Und stattdessen den File Owner auf diesen setzen? – tba

+0

Ich denke, du machst es dir schwerer, es so zu machen. Die Delegierung ist das, was Sie verwenden müssen, auch wenn Sie entscheiden, wo Sie Ihren Code haben möchten - in seiner eigenen Klasse oder in der View-Controller-Klasse, in der er verwendet wird. Es liegt natürlich an dir, aber ich glaube nicht, dass du etwas gewinnst, indem du es in eine eigene Klasse legst. Freundliche Grüße. –

0

Ja, IB auf dem iPhone möchte wirklich, dass der Eigentümer der Datei eine UIViewController-Unterklasse ist, was das, was Sie wollen, ein bisschen schwierig macht. Was Sie tun können, ist die Feder gegen einen bestehenden UIViewController lädt stattdessen eine der Instanziierung die Spitze mit:

@implementation QuizController 

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

@end 

, dass die Laufzeit bewirkt, dass die Spitze zu laden, aber anstatt einen neuen View-Controller zu schaffen, die Aktionen zu verbinden und Outlets wird es verwenden, was Sie als Besitzer übergeben. Da wir selbst in der Ansicht übergeben werden, die in dieser Nib definiert ist, wird sie an jedes IBOutlet angehängt, dem sie nach dem Aufruf zugewiesen wurde.

+0

Danke, das ist ein nützliches Snippet – tba

Verwandte Themen