不同设备的不同笔尖
Posted
技术标签:
【中文标题】不同设备的不同笔尖【英文标题】:Different Nibs for different devices 【发布时间】:2011-04-08 00:28:18 【问题描述】:所以我正在编写一个应用程序,我希望它是通用的。创建项目时,我创建了一个通用应用程序。我已经编写了所有的 iPhone 代码并且有 10 个类。现在我想创建 iPad 版本。与其拥有两组代码基本完全相同的类,我想根据设备类型加载不同的 Nib。
我尝试在应用程序委托中使用 BOOL,但遇到了问题。我尝试在 mainViewController 类(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
中进行设备检查,我根据设备类型返回了一个不同的笔尖。但我只能得到iphone版本或空白笔尖。提前感谢您的帮助。
【问题讨论】:
【参考方案1】:根据文档(资源编程指南),您可以使用如下命名约定: myNibName~ipad.xib 和 myNibName~iphone.xib 所以每个文件都只能在支持的设备上打开。你甚至不需要设置不同的 appDelegate :)
--- 来自文档 --- 在 ios 4.0 及更高版本中,可以将单个资源文件标记为仅在特定类型的设备上可用。此功能简化了您必须为通用应用程序编写的代码。您可以让捆绑加载例程选择正确的文件,而不是创建单独的代码路径来为 iPhone 加载一个版本的资源文件和为 iPad 加载不同版本的文件。您所要做的就是适当地命名您的资源文件。
要将资源文件与特定设备关联,您可以在其文件名中添加自定义修饰符字符串。包含此修饰符字符串会生成具有以下格式的文件名:
.
字符串代表资源文件的原始名称。它还代表您从代码访问文件时使用的名称。同样,字符串是用于标识文件类型的标准文件扩展名。该字符串是区分大小写的字符串,可以是以下值之一:
~ipad - 资源只能在 iPad 设备上加载。 ~iphone - 资源只能在 iPhone 或 iPod touch 设备上加载。
【讨论】:
“~ipad”和“~iphone”中的小写“p”对我来说感觉不对,但它确实是 Apple 所描述的。文档链接:developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/… 小写“p”非常重要。 ~iPad 可以运行模拟器,但无法在真实设备上加载。某些版本的 XCode 会创建 ~iPad 文件(带有大写的“P”),这会产生误导并且不起作用。 ^^ 感谢 Johan 和 Woj。我自己也很好奇。【参考方案2】:Apple 现在为您提供了一种默认机制,可在同一项目中将您的代码在 iPhone 和 iPad 之间分离。
在 Xcode 4 中,当您创建新的“基于窗口的应用程序”或“基于视图的应用程序”时,您可以选择“设备系列”。如果您为此选项选择“通用”,Xcode 将创建 3 个应用代理。
首先,一个主应用委托:
YourAppNameAppDelegate : NSObject <UIApplicationDelegate>
以及作为“YourAppNameAppDelegate”子类的另外两个应用代理(放置在不同的组中):
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。
这样您就可以在三个类之间拆分代码,在超类中保留与平台无关的东西 - 例如一些属性、方法、IBOutlets 和 IBActions - 并将特定于平台的实现放入任一子类中。
【讨论】:
有什么理由不进行转换?它是免费的.. developer.apple.com/xcode xcode 4 是公开发布还是处于测试阶段?我看到它处于测试阶段,并查看了所有主要变化,只是想我会坚持一些我失败的东西。我不经常查看 dev.apple.com 已公开发布。虽然我弄错了,但如果你是 iOS 开发者计划的一部分,它才是免费的。否则 4.99 美元。 我在 iOS 付费开发者计划中。我想我会得到它【参考方案3】:我遇到过这个问题,通过自定义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”。
【讨论】:
看起来很酷,但是当 iPad 3 或 4 有 Retina 显示屏然后你被@HD@2x 卡住时会发生什么。那会是一团糟。【参考方案4】:我想通了:
在Interface Builder中,使用File->Create ipad version
然后保存文件,并将其添加到项目中。然后在分配时,初始化每个viewController,检查是否UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad
,否则它是一个iPhone 或iPod Touch。初次保存后我无法对其进行编辑,但它可以工作。
【讨论】:
以上是关于不同设备的不同笔尖的主要内容,如果未能解决你的问题,请参考以下文章
UITableViewHeaderFooterView 不支持笔尖中的自动布局约束