为啥自定义 xib 需要 UIView 属性
Posted
技术标签:
【中文标题】为啥自定义 xib 需要 UIView 属性【英文标题】:Why does custom xib require UIView property为什么自定义 xib 需要 UIView 属性 【发布时间】:2015-11-05 19:16:43 【问题描述】:我按照此处概述的教程在我的视图控制器中加载自定义 xib。
xib的类继承自UIView但也需要一个属性视图:
@interface MYBannerView : UIView
@property (nonatomic, weak) IBOutlet UIView *view;
@end
我觉得它需要这个很奇怪,因为它就像在一个看起来多余的视图中拥有一个视图。这有什么特别的原因吗?
编辑
我在这里按照本教程进行了概述:
http://www.maytro.com/2014/04/27/building-reusable-views-with-interface-builder-and-auto-layout.html
【问题讨论】:
理论上你不需要这个属性,你可以使用self... 为什么需要它?你在哪里读到的? 我添加了我用作教程的原始链接 下面给出具体答案。但实际上,如果您正在学习 ios,那么您应该将 CONTAINER VIEWS 用于任何类似的事情。现在一切都是容器视图。它们使用起来绝对是微不足道的——这是 Apple 在编程效率方面的惊人进步。 Long tutorial 关于具体问题,我真的强烈建议您忽略您链接到的特定教程。如果 - 出于某种原因 - 你想这样做。 (或者,如果您正在使用 1990 年的时间机器阅读这篇文章,当时还没有简单的容器视图 :))... 就这样做***.com/a/21073901/294884 更多关于同一主题的信息... ***.com/a/25910881/294884 【参考方案1】:当MYBannerView
以编程方式初始化时,该教程的作者正在使用视图出口从 xib 加载视图
- (instancetype)initWithCoder:(NSCoder *)aDecoder
self = [super initWithCoder:aDecoder];
if (self)
NSString *className = NSStringFromClass([self class]);
self.view = [[[NSBundle mainBundle] loadNibNamed:className owner:self options:nil] firstObject];
[self addSubview:self.view];
return self;
return nil;
在 Interface Builder 中创建的任何内容都不会使用程序化 init
加载。 loadNibNamed
从 xib 加载 UI。
如果您想覆盖 initWithFrame:
以从 xib 加载 UI 元素,您的 init 方法将如下所示:
- (instancetype)initWithFrame:(CGRect)frame
self = [super initWithFrame:frame]; // initialize your objects
if (self)
[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:self options:nil]; // load your view from IB
return self; // return the view with all of the IB UI loaded
【讨论】:
仍然不是 100% 清楚。据我了解,当以编程方式加载 XIB 时,将调用 initWithFrame 并且仅在使用 IB 中的相关类设置 UIView 时才调用 initWithCoder。我想要得到的是:是否可以创建一个 XIB,将带有 IB 的 UI 组件添加到文件所有者,然后使用 initWithFrame 以编程方式初始化。 为了初始化使用界面生成器创建的任何 UIView 对象,您必须调用loadNibNamed:
以便从 xib 加载视图。我编辑了我的帖子以显示initWithFrame:
的示例
感谢您迄今为止的建议。所以澄清一下,如果我要通过 IB 在 XIB 上添加一些按钮和标签,然后以编程方式加载 IB(这将调用 initWithFrame),那么这些标签和按钮不会加载?
不完全。如果您以编程方式调用任何 init
方法(init:
、initWithCoder:
、initWithFrame:
),除非您覆盖初始化程序以调用 loadNibNamed:
,否则不会加载界面构建器视图。
您可以在此问题中阅读有关此行为的更多信息:***.com/q/21722805/2415822【参考方案2】:
不,您的UIView
子类不需要视图的出口才能正常工作。事实上,使用self
您可以访问视图本身。
教程呢:当作者在MYViewController's
视图上添加view A
(我们这样称呼它)时,他将view A
类设置为MYBannerView
。正在运行的应用程序不会显示任何内容,因为 MYBannerView
xib 没有加载并且没有替换来自 view A
的内容。所以作者在initWithCoder
中加载这个xib,使用loadNibNamed:
返回的值设置出口,并将从MYBannerView
加载的视图添加到view A
。这个过程有点混乱,但它有效。
【讨论】:
以上是关于为啥自定义 xib 需要 UIView 属性的主要内容,如果未能解决你的问题,请参考以下文章
如何将额外参数传递给链接到 XIB 文件的自定义 UIView?