问题的由来
问题一:我们经常会遇到在xib中的某一部分,我们在另外一个自定义View里面也能用到,我们可以将这部分重新搞一个xib来描述,多个用到的地方直接放上就可以.
问题二:我们的用xib描述一个View,有一个button我们需要自定义.并且这个按钮又是xib描述的
上面遇到的问题其实都是一个问题,xib的嵌套.
我们正常操作有什么问题呢?
我们正常的操作就是就是在当前的xib的子控件(又是用xib描述的)的类名就进行设置,就应该正常加载子控件.
然而实际效果不是这样的,我们这样操作就子控件xib描述的控件都不能正常显示.
Snip20220416_21.png
原因是什么呢?
控件不显示,我们去查一下,在当前控件的awakeFromeNib 方法中增加断点调试发现,他的子控件都是nil,这种表现显然是没有被初始化,我们必须来强制让他初始化加载一下.
如何解决这个问题?
这里我只讲比较简单理解的方法.
方法就是将和子控件同名的xib文件的File owner 设为子控件的类,特比需要注意的是这时xib的类名就不要进行绑定了.我们知道File owner的作用是将xib描述的控件当做 file owner 绑定类名的属性,这时我们就可以将xib描述的子控件加到当前类中.
具体当前的例子就是把MyView.xib这个文件描述的控件作为一个子控件,添加到MyView.h 和MyView.m描述的MyView类中.
具体代码如下:
- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super initWithCoder:aDecoder]) {
UIView *containerView = [[[UINib nibWithNibName:@"MyView" bundle:nil] instantiateWithOwner:self options:nil] objectAtIndex:0];
CGRect newFrame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
containerView.frame = newFrame;
[self addSubview:containerView];
##上面的代码已经可以了,如果还想在代码中添加一些控件或者做一些其他设置,我们可以在后面添加就可以.
UISwitch *twoSwi = [UISwitch new];
twoSwi.frame = CGRectMake(0, 0, 40, 30);
[self addSubview:twoSwi];
NSLog(@"MyView initWithCoder");
}
return self;
}
网友评论