不同的Nib用于不同的设备

时间:2011-04-08 00:28:19

标签: iphone objective-c ipad xib nib

所以我正在编写一个应用程序,我希望它能够普及。当我创建项目时,我创建了一个通用应用程序。我已经编写了所有的iPhone代码,并且有10个类。现在我要创建iPad版本。我希望根据设备类型加载不同的Nib,而不是让两组基本上使用完全相同的代码。

我尝试在app委托中使用BOOL并遇到麻烦。我在mainViewController类(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil中尝试了设备检查。我根据设备类型返回了一个不同的nib。但我只能得到iPhone版本或空白笔尖。提前感谢您的帮助。

4 个答案:

答案 0 :(得分:6)

根据文档(资源编程指南),您可以使用名称约定,如: myNibName~ipad.xib和myNibName~iphone.xib所以每个文件只能在支持的设备上打开。您甚至不需要设置不同的appDelegates:)

---来自doc --- 在iOS 4.0及更高版本中,可以将各个资源文件标记为仅在特定类型的设备上可用。此功能简化了您必须为Universal应用程序编写的代码。您可以让捆绑加载例程选择正确的文件,而不是创建单独的代码路径来为iPhone加载一个版本的资源文件,为iPad加载不同版本的文件。您所要做的就是适当地命名您的资源文件。

要将资源文件与特定设备相关联,请在其文件名中添加自定义修饰符字符串。包含此修饰符字符串会产生具有以下格式的文件名:

该字符串表示资源文件的原始名称。它还表示从代码访问文件时使用的名称。同样,字符串是用于标识文件类型的标准文件扩展名。该字符串是区分大小写的字符串,可以是以下值之一:

~ipad - 资源只能加载到iPad设备上。 ~iphone - 资源只能加载到iPhone或iPod touch设备上。

答案 1 :(得分:1)

Apple现在为您提供了一种默认机制,可以在同一个项目中将您的代码在iPhone和iPad之间分开。

在Xcode 4中,当您创建新的“基于窗口的应用程序”或“基于视图的应用程序”时,您可以选择“设备系列”。如果您为此选项选择“通用”,Xcode将创建3个应用代表。

首先,主应用代表:

YourAppNameAppDelegate : NSObject <UIApplicationDelegate> 

和另外两个作为“YourAppNameAppDelegate”子类的app委托(放在不同的组中):

YourAppNameAppDelegate_iPhone : YourAppNameAppDelegate
YourAppNameAppDelegate_iPad : YourAppNameAppDelegate

当您使用iPhone或iPad模拟器(或设备)运行应用程序时,应用程序将根据所选设备自动使用_iPhone或_iPad应用程序委托子类。

如果你在每个子类中覆盖application:didFinishLaunchingWithOptions:方法,你会看到这个工作:

// In YourAppNameAppDelegate_iPhone.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSLog(@"iPhone App Delegate");
    return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

// In YourAppNameAppDelegate_iPad.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSLog(@"iPad App Delegate");
    return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

这为您提供了一个起点,您可以根据用户所在的设备更改程序流程。例如,通过实例化主视图控制器的一个子类(如下所述)。

在向项目中添加新的视图控制器时,您应该通过创建一个通用控制器超类和一个特定于iPhone / iPad的子类来继续使用此范例。请注意,通用超类不应该有与之关联的nib文件,而子类应该各自都有自己独立的nib。

通过这种方式,您可以在三个类之间中断代码,在超类中保留与平台无关的内容 - 例如一些属性,方法,IBOutlet和IBActions - 并将特定于平台的实现放入任何子类中。

答案 2 :(得分:0)

我遇到了这个问题,我通过自定义UIViewController的initWithNibName:bundle:方法解决了这个问题。

- (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle*)nibBundleOrNil
{
  // See below for definition of "LWEUniversalAppHelpers fileNamed:"
  NSString *universalNibName = [LWEUniversalAppHelpers fileNamed:nibNameOrNil];
  if ((self = [super initWithNibName:universalNibName bundle:nibBundleOrNil]))
  {
    // Custom initialization
  }
  return self;
}

LWEUniversalAppHelpers是我公司编写的帮助程序类,用于确定设备是否为iPad。这是public on GitHub,但基本概念是使用Retina的“@ 2x”政策,而是使用“@HD”。

答案 3 :(得分:0)

我想出了:

<>在Interface Builder中,使用File-&gt; Create ipad version

然后保存文件,并将其添加到项目中。然后在alloc时,初始化每个viewController,检查是否UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad,还是iPhone或iPod Touch。我在初始保存后对它进行编辑时遇到了麻烦,但它确实有效。