2009-08-12 74 views
7

我正在设计一个简单的测验应用程序。应用程序需要显示不同类型的QuizQuestions。 QuizQuestion的每种类型都有独特的行为和用户界面。iPhone子视图设计(UIView与UIViewController)

的用户界面将是这样的: alt text http://dl.getdropbox.com/u/907284/Picture%201.png

我想能够设计每种类型QuizQuestion的界面生成器。

例如,MultipleChoiceQuizQuestion应该是这样的: alt text http://dl.getdropbox.com/u/907284/Picture%202.png

本来,我打算让QuizQuestion类一个UIViewController。不过,我在Apple文档中读到,UIViewControllers只能用于显示整个页面。

因此,我让我的QuizController(管理整个屏幕,例如prev/next按钮)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 
} 

这种类型的访问似乎没有成为标准的或面向对象的。这种类型的代码是否正常/可以接受?或者我在设计的某个地方做出了糟糕的选择?

三江源,

编辑(为了清楚起见):我想有一个单独的类来控制multipleChoiceView ......就像一个视图控制器,但显然这只是对整个窗口。也许我应该制作一个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. 
} 

其中选择题视图和openEndedView在你QuizController连接到你在IB设计视图UIView的网点。您可能需要在父视图中混淆视图的位置,才能将其添加到正确位置,但可以通过调用UIView上的-setBounds/-setFrame和/或-setCenter 。

+0

谢谢,但我想有一个单独的类来控制multipleChoiceView ...就像一个ViewController,但显然这只适用于整个窗口。 也许我应该制作一个MultipleChoiceViewManager(不是控制器!)并将文件所有者设置为该文件? – tba 2009-08-12 07:15:38

+0

我认为你这样做会更难。委派是你必须使用的,无论如何你的决定是关于你想要你的代码的地方 - 在它自己的类或者视图控制器类中它将被使用的地方。这显然取决于你,但我认为你将它放在自己的课堂上是无所不能的。最好的祝福。 – 2009-08-12 07:40:55

0

是的,IB上的iPhone真的希望File's Owner是一个UIViewController子类,这使得你想要有点棘手。你可以做的是加载对现有的UIViewController笔尖,而不是使用笔尖实例之一:

@implementation QuizController 

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

@end 

这将导致运行时加载的笔尖,而不是创建一个新的视图控制器的动作连接和它将使用你作为所有者传入的内容。由于我们在视图中定义的视图中传递self,所以它将被附加到在调用之后分配给它的任何IBOutlet。

+0

谢谢你是一个有用的代码段 – tba 2009-08-12 07:22:56