如何将 NIB 文件的使用引入我现有的自定义 UIView?例如:
a) 如果将名称命名为 *.h 和 *.m 文件,NIB 是否应该以某种方式自动加载? (即我在这里谈论的是自定义 UIView,而不是 UIControllerView)
b) 如果必须手动执行,是否需要使用“[[NSBundle mainBundle] loadNibNamed:@"NIBfilename"owner:self options:nil];"也许?
c) 如果是(对上面的 b),那么您是否在自定义 View 的“- (id)initWithCoder:(NSCoder *)coder”方法中执行此操作?
附言。用于与@Katfish 的回答进行讨论。 Katfish,当我将“NSArray *nibs = [[NSBundle mainBundle]...”行放入时,我得到了一个递归循环的命中“initWithCoder”? [PS 请参阅我刚刚对 @sergio 的回答发表的评论,这可能解释了这一点?]
// Code within my custom UIView
- (id)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
if (self) {
NSArray *nibs = [[NSBundle mainBundle] loadNibNamed:@"ClockView" owner:self options:nil];
self = [nibs objectAtIndex:0];
.
.
.
}
return self;
}
附言。注意到我到这里的状态(参见 Sergio 的回答中的评论)我现在想知道我正在做的事情是否有可能?基于看到Custom UIView from Interface Builder .也许我可以创建一个自定义 UIView,但只能通过从我调用它的 UIControllerView 以编程方式创建/实例化它来使用?
最佳答案
a) should the NIB load automatically somehow if named the name as the *.h & *.m file? (i.e. I'm talking about a custom UIView here, not a UIControllerView)
据我所知,nib 不会自动加载,除了 MainWindow,它是由 UIKit 根据它在 info.plist 中指定的内容加载的;
b) if you have to do it manually do you need to use "[[NSBundle mainBundle] loadNibNamed:@"NIBfilename" owner:self options:nil];" perhaps?
loadNibNamed
如果您不想实例化 View Controller 并且只需要您在 nib 中定义的顶级对象的数组,那么这是一个不错的选择;
c) if yes (to b above), then in whether method do you do this, in the custom view's "- (id)initWithCoder:(NSCoder *)coder" method?
如果您从 nib 加载基本 View ,我会使用 initWithCoder
,如果您以编程方式创建它,我会使用 initWithFrame
。
编辑:
关于您的 PS,我猜您将 xib 文件中的对象之一设置为 UIView
子类的实例,您在其中定义了 initWithCoder
。 (例如,如果您的 UIView
子类是 MyView
,那么您还在 xib 中实例化了一个 View 对象并将其类设置为 MyView
)。
如果是这种情况,您需要做的是将 File's Owner 定义为具体派生的 UIView
类(例如,MyView
);事实上,您已经在实例化 UIView
派生类,并且在加载 Nib 时您只需要指定文件的所有者(通过 owner
参数)。
编辑 2:
哦实际上我看到事实上我有 (a) 在使用我的自定义 View 的父 UIControllerView 中,在 IB 中因为它是 XIB 我使用了一个 UIView 我已经将类名设置为“clockview”,但是然后 (b ) 在我实际的 clockview 自定义 UIView(不是 UIControllerView)XIB 文件中我做了同样的事情并将类名设置为“clockview”。你知道我应该为 (a) 父 UIControllerView 和 (b) 自定义 UIView 本身使用什么类名吗? (有点困惑)- 格雷格 1 小时前
阅读您的评论后,您有两种方法:
第一个选项
在你的
UIViewController
相关的 xib 中,你做得对;在您的其他 xib 文件中,删除自定义
UIView
(您分配了类名clockview
的那个;此对象将已由 xib 创建第1点,所以你不需要再次实例化它);选择此“其他 xib”的文件所有者并将其类名设置为clockwork
。
在这种情况下,您将像以前一样定义 initWithCoder
。这样做的缺点是您在一个 Nib 中实例化对象而在另一个 Nib 中实例化 View ;您将无法在第二个 Nib 中定义时钟 View View 。所以,...
第二个选项
在你的
UIViewController
相关的xib中,更改UIView
类名并将其设置为UIView
;因此,此 View 将是一个“普通” View ,您将用作空 View 来托管第二个 xib 文件中的另一个 View ;在您的其他 xib 文件中,保持原样;在这种情况下,您可能可以将文件所有者设置为第 1 点的
UIViewController
。
我认为这第二种情况是您针对的情况。在这种情况下,您无需在时钟 View 的 initWithCoder
中执行任何特定操作;您需要的是,在您的 UIViewController
中,在适当的时候加载 xib View ;通常这可能在 viewDidLoad
中(或其他地方,可能在您单击按钮后,这取决于您的应用程序):
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *nibs = [[NSBundle mainBundle] loadNibNamed:@"ClockView" owner:self options:nil];
for (NSObject *obj in nibs) {
if ( [obj isKindOfClass:[clockview class]]) {
[self addSubview:(clockview*)obj];
break;
}
}
}
我在这个 viewDidLoad
中所做的是识别通过加载第二个 xib 文件实例化的发条 View ;并将其作为 subview 添加到 Controller 的 View 中。
再次观察我传递给 loadNibNamed
的 controller
参数;这必须对应于您指定为第二个 xib 文件所有者的对象。
我认为它应该以这种方式工作。
关于iphone - 如何将 NIB 文件的使用引入我现有的自定义 UIView?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6675375/