2009-08-12 2 views
7

Я разрабатываю простое приложение Quiz. Приложение должно отображать различные типы QuizQuestions. Каждый тип QuizQuestion имеет четкое поведение и пользовательский интерфейс.iPhone subview design (UIView vs UIViewController)

Пользовательский интерфейс будет выглядеть примерно так: alt text http://dl.getdropbox.com/u/907284/Picture%201.png

Я хотел бы быть в состоянии проектировать каждый тип QuizQuestion в Interface Builder.

Например, MultipleChoiceQuizQuestion будет выглядеть следующим образом: alt text http://dl.getdropbox.com/u/907284/Picture%202.png

Первоначально я планировал сделать QuizQuestion класс UIViewController. Тем не менее, я прочитал в документации Apple, что UIViewControllers следует использовать только для отображения всей страницы.

Поэтому я сделал свой QuizController (который управляет всем экраном, например, предыдущими/предыдущими), UIViewController и мой класс QuizQuestion - подкласс UIView.

Однако, чтобы загрузить этот UIView (создан в IB), я должен [1] сделать следующее в моем конструкторе:

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

Этот тип доступа, кажется, не быть стандартным или объектно-ориентированным. Является ли этот тип кода нормальным/приемлемым? Или я сделал плохой выбор где-то в моем дизайне?

Thankyou,

редактировать (для ясности): Я хотел бы иметь отдельный класс для управления multipleChoiceView ... как ViewController но, видимо, это только для целых окон. Может быть, я должен сделать MultipleChoiceViewManager (а не контроллер!) И установить вместо этого владельца файла?

ответ

5

Вы на правильном пути. В вашем QuizController xib вы можете создавать отдельные виды, перетаскивая их в главное окно xib, а не в основное представление QuizController. Затем вы можете спроектировать каждый вид, который вам нужен, в соответствии с вашими типами вопросов. Когда пользователь нажимает следующий или предыдущий, удалите предыдущее представление и загрузите представление, которое вам нужно, на основе вашего типа вопроса, используя -addSubview на главном экране контроллера просмотра и отслеживайте, какой субвью отображается в данный момент. Пытаясь что-то вроде этого:

[currentView removeFromSuperView]; 

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

Где multipleChoice вид и openEndedView является UIView розетки в вашем QuizController, связанный с видом вы разработанным в IB. Возможно, вам придется столкнуться с позицией вашего представления в родительском представлении, прежде чем добавить его, чтобы он отображался в нужном месте, но вы можете сделать это с помощью вызовов -setBounds/-setFrame и/или -setCenter в UIView ,

+0

Спасибо, но я хотел бы иметь отдельный класс для управления multipleChoiceView ... как ViewController, но, видимо, это только для целых окон. Может быть, я должен сделать MultipleChoiceViewManager (а не контроллер!) И вместо этого установить для этого владельца файла? – tba

+0

Я думаю, что вы делаете это сложнее, когда вы так делаете. Делегирование - это то, что вы должны использовать независимо от того, что ваше решение касается того, где вы хотите, чтобы ваш код - в своем классе или в классе контроллера вида, где он будет использоваться. Это, очевидно, зависит от вас, но я не думаю, что вы что-то набираете, разместив его в своем классе. С наилучшими пожеланиями. –

0

Да, IB на iPhone действительно хочет, чтобы владелец файла был подклассом UIViewController, который делает то, что вы хотите немного сложнее. Что вы можете сделать, это загрузить перо против существующего UIViewController вместо инстанцирования один, используя перо:

@implementation QuizController 

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

@end 

Это приведет к среде выполнения загрузки пера, но вместо того чтобы создавать новый контроллер представления для подключения действия и он будет использовать то, что вы передаете как владелец. Поскольку мы передаем себя в виде, определенном в том, что nib будет привязан к любому IBOutlet, который вы назначили после вызова.

+0

Спасибо, что это полезный снипп – tba

Смежные вопросы