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

相关问题