2009-08-12 37 views
7

Tôi đang thiết kế một ứng dụng Quiz đơn giản. Ứng dụng cần hiển thị các loại QuizQuestions khác nhau. Mỗi loại QuizQuestion có một hành vi và giao diện người dùng riêng biệt.Thiết kế iPhone subview (UIView vs UIViewController)

Giao diện người dùng sẽ được một cái gì đó như thế này: alt text http://dl.getdropbox.com/u/907284/Picture%201.png

Tôi muốn để có thể thiết kế từng loại QuizQuestion trong Interface Builder.

Ví dụ, một MultipleChoiceQuizQuestion sẽ trông như thế này: alt text http://dl.getdropbox.com/u/907284/Picture%202.png

Ban đầu, tôi lên kế hoạch để làm cho lớp QuizQuestion một UIViewController. Tuy nhiên, tôi đọc trong tài liệu của Apple rằng UIViewControllers chỉ nên được sử dụng để hiển thị toàn bộ trang.

Vì vậy, tôi đã thực hiện QuizController (quản lý toàn bộ màn hình, ví dụ: nút prev/next) UIViewController và lớp QuizQuestion của tôi là lớp con của UIView.

Tuy nhiên, để tải UIView này (tạo ra trong IB), tôi phải [1] làm như sau trong constructor của tôi:

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

Đây là loại truy cập dường như không có tiêu chuẩn hoặc hướng đối tượng. Loại mã này có bình thường/được chấp nhận không? Hay tôi đã chọn một người nghèo ở đâu đó trong thiết kế của tôi?

Thankyou,

chỉnh sửa (cho rõ ràng): Tôi muốn có một lớp riêng biệt để kiểm soát multipleChoiceView ... như một ViewController nhưng dường như đó là chỉ cho toàn bộ cửa sổ. Có lẽ tôi nên tạo một MultipleChoiceViewManager (không phải bộ điều khiển!) Và thiết lập chủ sở hữu của tập tin để thay thế?

Trả lời

5

Bạn đang đi đúng hướng. Trong QuizController xib của bạn, bạn có thể tạo các khung nhìn riêng biệt bằng cách kéo chúng vào cửa sổ chính của xib chứ không phải là khung nhìn chính của QuizController. Sau đó, bạn có thể thiết kế mỗi chế độ xem bạn cần theo các loại câu hỏi của bạn. Khi người dùng nhấn tiếp theo hoặc trước đó, hãy xóa chế độ xem trước đó và tải chế độ xem bạn cần dựa trên loại câu hỏi của bạn bằng cách sử dụng -addSubview trên chế độ xem chính của trình điều khiển chế độ xem và theo dõi xem tiểu sử nào hiện đang hiển thị. Hãy thử một cái gì đó như thế này:

[currentView removeFromSuperView]; 

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

Trường hợp chế độ xem nhiềuChọn và mởEndedView là cửa hàng UIView trong Quiz của bạnĐiều khiển kết nối với quan điểm bạn thiết kế trong IB. Bạn có thể cần phải lộn xộn với vị trí của chế độ xem của bạn trong chế độ xem gốc trước khi bạn thêm nó vào để hiển thị ở đúng vị trí, nhưng bạn có thể thực hiện điều này với các lệnh gọi đến -setBounds/-setFrame và/hoặc -setCenter trên UIView .

+0

Cảm ơn nhưng tôi muốn có một lớp riêng biệt để kiểm soát multipleChoiceView ... giống như một ViewController nhưng dường như chỉ dành cho toàn bộ cửa sổ. Có lẽ tôi nên tạo một MultiChoiceViewManager (không phải bộ điều khiển!) Và đặt Chủ sở hữu của tệp thành thay thế đó? – tba

+0

Tôi nghĩ rằng bạn đang làm cho nó khó khăn hơn vào chính mình làm theo cách đó. Ủy quyền là những gì bạn phải sử dụng bất kể quyết định của bạn là về nơi bạn muốn mã của bạn - trong lớp riêng của nó hoặc trong lớp trình điều khiển chế độ xem nơi nó sẽ được sử dụng. Nó rõ ràng là tùy thuộc vào bạn, nhưng tôi không nghĩ bạn đang đạt được bất cứ điều gì bằng cách đặt nó trong lớp riêng của nó. Trân trọng. –

0

Vâng, IB trên iPhone thực sự muốn Chủ sở hữu tệp là lớp con UIViewController, điều này làm cho những gì bạn muốn một chút khéo léo. Những gì bạn có thể làm là tải các ngòi chống lại một UIViewController hiện tại thay vì instantiating một bằng cách sử dụng ngòi:

@implementation QuizController 

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

@end 

Điều đó sẽ làm cho thời gian chạy để nạp ngòi, nhưng thay vì tạo ra một bộ điều khiển xem mới để kết nối các hành động và cửa hàng nó sẽ sử dụng những gì bạn vượt qua như là chủ sở hữu. Kể từ khi chúng tôi vượt qua tự trong chế độ xem được xác định trong nib đó sẽ được gắn liền với bất kỳ IBOutlet bạn có nó được chỉ định sau khi cuộc gọi.

+0

Cảm ơn đó là đoạn mã hữu ích – tba

Các vấn đề liên quan