在视图控制器中动态加载 iPhone/iPad 的 nib
Posted
技术标签:
【中文标题】在视图控制器中动态加载 iPhone/iPad 的 nib【英文标题】:Dynamically load nib for iPhone/iPad within view controller 【发布时间】:2011-03-04 09:31:17 【问题描述】:我已经使用 XCode 中的向导将 iPhone 应用程序转换为通用应用程序。
它构建得很好,但在某些地方显然看起来有点垃圾:)
我需要根据正在使用的设备加载笔尖。我不希望使用initWithNib
创建我的视图控制器,因为我已经有代码来创建带有一些数据(initWithMyLovelyData
)的控制器,这与 nib 加载没有任何关系。
我知道要找出您使用的设备UI_USER_INTERFACE_IDIOM()
,所以我尝试在实际视图控制器本身中覆盖initWithNibName
,假设它们以某种方式在内部被调用。但它不起作用,因为我想我不确定语法。
我试过了
if(ipad..) self = [super initWithNibName:@"MyIpadNib" bundle:nibBundleOrNil];
这不起作用:/
编辑 - 我知道我已经对此进行了大量编辑,在进行更多研究后使我的问题更加具体 - 道歉!
【问题讨论】:
【参考方案1】:编辑:@Adam 下面的答案是正确答案。
要确定要加载哪个 nib,请执行以下操作,并废弃您的 initWithMyLovelyData
方法并使用属性来设置数据。您应该能够轻松地将所有初始化代码移动到属性设置器方法中。
MyViewController *viewController;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
viewController = [[MyViewController alloc] initWithNibName:@"ipadNIB" bundle:nil];
else
viewController = [[MyViewController alloc] initWithNibName:@"iphoneNIB" bundle:nil];
viewController.myLovelyData = someData;
【讨论】:
抱歉挖掘旧(呃)帖子,但是:这对我不起作用。有什么想法吗? @Linuxmint 你有什么问题? ***.com/questions/5306346/… FWIW,@adam 的答案是正确的,而且比这要好得多。 由于 nib 名称只是两个字符串之一,其余的 VC 分配/初始化是相同的,您可以通过只调用一次 alloc/init VC 来缩短代码,使用一个 NSString 变量,设置为一个 nib 名称或另一个。【参考方案2】:我只是将这两个方法放在一个名为 IPadHelper 的类中,并使用 addIPadSuffixWhenOnIPad 方法根据平台有条件地在两个 nib 之间进行选择
+ (BOOL)isIPad
if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iPhoneOS_3_2)
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
return YES;
return NO;
+ (NSString *)addIPadSuffixWhenOnIPad:(NSString *)resourceName
if([IPadHelper isIPad])
return [resourceName stringByAppendingString:@"-iPad"];
else
return resourceName;
第一种方法的更多解释见这里 http://cocoawithlove.com/2010/07/tips-tricks-for-conditional-ios3-ios32.html...
【讨论】:
编译器说这是错误的,因为Class方法应该返回对象(id)。因此,如果认为将其添加到 C 文件中会更好。【参考方案3】:你也可以吃蛋糕。只需添加一个包装 initWithNibName:bundle: 的方法并添加您的 myLovelyData 参数:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil myLovelyData:(id)data
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]))
// Custom initialization using myLovelyData
//
return self;
【讨论】:
【参考方案4】:我认为创建 C 文件会更好。 文件助手.h
#import <Foundation/Foundation.h>
BOOL isIPad();
NSString *addIPadSuffixWhenOnIPad(NSString *resourceName);
FileHelper.m
#import "FileHelper.h"
BOOL isIPad()
if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iPhoneOS_3_2)
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
return YES;
return NO;
NSString *addIPadSuffixWhenOnIPad(NSString *resourceName)
if(isIPad())
return [resourceName stringByAppendingString:@"-iPad"];
else
return resourceName;
【讨论】:
【参考方案5】:实际上,Apple 会自动执行所有这些操作,只需命名您的 NIB 文件即可:
MyViewController~iphone.xib // iPhone
MyViewController~ipad.xib // iPad
并用最少的代码加载您的视图控制器:
[[MyViewController alloc] initWithNibName:nil bundle:nil]; // Apple will take care of everything
【讨论】:
如果你使用这个语句:[MyViewController alloc] init];相反,在上面的示例中,它是否在做完全相同的事情?还是它在做一些稍微不同的事情? 我希望“init”什么都不做。如果你想让它加载一个 NIB,你需要调用 initWithNib - 或者手动从包中加载一个 NIB [[MyViewController alloc] init] 与 [[MyViewController alloc] initWithNibName:nil nibBundle:nil] 完全相同,在 UIViewController.h 文件中提到:“如果你继承 UIViewController,你必须调用此方法的超级实现,即使您没有使用 NIB。(为方便起见,默认的 init 方法会为您执行此操作,并为此方法的两个参数指定 nil。)" 这是在哪里记录的? UIViewController 中“nibName”的文档指定了在没有提供时如何解析 nib 名称,但似乎没有提及这种方法。 只想补充一点,描述“iOS 支持设备特定资源”的文档部分可以在这里找到:developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/…以上是关于在视图控制器中动态加载 iPhone/iPad 的 nib的主要内容,如果未能解决你的问题,请参考以下文章
iPhone / iPad 表格视图仅重新加载一行而不是整个表格
是否有用于在表格视图控制器上编辑字段的 iPhone/iPad 库?