0

我是新來的Objective-C所以,忍受我。我開始使用Xcode4中的通用應用程序模板並構建了我的應用程序。有一個約定,模板以我試圖堅持的方式開始。對於每個View Controller,每個設備類型都有一個主文件和一個子類。例如:在通用應用程序中實例化設備特定視圖控制器的正確模式是什麼?

Project/ 
    ExampleViewController.(h|m) 
    - iPhone/ 
     - ExampleViewController_iPhone.(h|m|xib) 
    - iPad/ 
     - ExampleViewController_iPad.(h|m|xib) 

大多數情況下,這是非常方便的。大多數邏輯都在超類中,而子類負責任何特定於設備的實現。

這是我沒有得到的部分。有時候我有代碼在每個子類中執行相同的,因爲我需要爲每個設備加載不同的xib。例如:

ExampleViewController_iPhone

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    Content *selectedContent = (Content *)[[self fetchedResultsController] objectAtIndexPath:indexPath]; 
    ContentDetailViewController_iPhone *detailViewController = [[ContentDetailViewController_iPhone alloc] init]; 
    detailViewController.content = selectedContent; 
    detailViewController.managedObjectContext = self.managedObjectContext; 

    [self.navigationController pushViewController:detailViewController animated:YES]; 
    [detailViewController release]; 
} 

ExampleViewController_iPad

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    Content *selectedContent = (Content *)[[self fetchedResultsController] objectAtIndexPath:indexPath]; 
    ContentDetailViewController_iPad *detailViewController = [[ContentDetailViewController_iPad alloc] init]; 
    detailViewController.content = selectedContent; 
    detailViewController.managedObjectContext = self.managedObjectContext; 

    [self.navigationController pushViewController:detailViewController animated:YES]; 
    [detailViewController release]; 
} 

...注意到,在二審中唯一不同的是,它裝載_iPad版視圖控制器。這是必要的,因爲iPadiPhone視圖控制器被連接到單獨的設備特定節點。

這樣做的「正確」模式是什麼?


UPDATE

我發現this answer有關使用設備修飾符這似乎是它可以在我並不需要一個特定的子類,一個元件的情況下幫助您在加載單獨xibs,但仍然贏得了如果我需要實例化特定功能的視圖控制器的特定_iPhone_iPad實例,將無濟於事。

回答

1

有兩種簡單的方法可以解決您的問題。放入你的超類時,兩者都可以工作。

第一種方法只適用,因爲你有兩個不同的類,其中一個創建取決於所使用的設備。它不會工作,如果你不使用不同的類,因爲沒有設備特定的代碼。它涉及要求對象的類來決定它是什麼。由於對象的類將特定的設備類,即使超類要求,您可以查看哪個類創建並採取相應的行動。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    Content *selectedContent = (Content *)[[self fetchedResultsController] objectAtIndexPath:indexPath]; 
    Class classToUse; 
    if([self class] == [ExampleViewController_iPad class]) { 
     // We are running on the iPad 
     classToUse = [ContentDetailViewController_iPad class]; 
    } else { 
     // We must be running on either the iPhone or iPod touch 
     classToUse = [ContentDetailViewController_iPhone class]; 
    } 
    // Just use superclass for typing here, since we aren't doing anything device specific 
    ContentDetailViewController *detailViewController = [[classToUse alloc] init]; 
    detailViewController.content = selectedContent; 
    detailViewController.managedObjectContext = self.managedObjectContext; 

    [self.navigationController pushViewController:detailViewController animated:YES]; 
    [detailViewController release]; 
} 

第二種方法可以在程序中的任何位置工作。 Apple在iOS 3.2中爲UIDevice類添加了一個屬性,稱爲「用戶界面習慣用法」。目前有兩種可能的值:UIUserInterfaceIdiomPadUIUserInterfaceIdiomPhone。由於這些不之前的版本3.2的存在,蘋果還加入了宏將從該物體的UIDevice返回UIUserInterfaceIdiomPhone如果版本低於3.2,並得到實際值如果大於或等於3.2。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    Content *selectedContent = (Content *)[[self fetchedResultsController] objectAtIndexPath:indexPath]; 
    Class classToUse; 
    // If you aren't supporting versions prior to 3.2, you can use [UIDevice currentDevice].userInterfaceIdiom instead to save a couple of cycles 
    if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { 
     // We are running on the iPad 
     classToUse = [ContentDetailViewController_iPad class]; 
    } else { 
     // We must be running on either the iPhone or iPod touch 
     classToUse = [ContentDetailViewController_iPhone class]; 
    } 
    // Just use superclass for typing here, since we aren't doing anything device specific 
    ContentDetailViewController *detailViewController = [[classToUse alloc] init]; 
    detailViewController.content = selectedContent; 
    detailViewController.managedObjectContext = self.managedObjectContext; 

    [self.navigationController pushViewController:detailViewController animated:YES]; 
    [detailViewController release]; 
} 
+0

1對於一個簡單的,優雅和很好地解釋溶液。正是我需要的。我沒有意識到你可以在Objective C中存儲一個類引用以備後用,所以你的例子特別有用。謝謝! – markquezada 2011-04-12 18:59:43

相關問題