前言
<p>最近要重构公司的几个项目,不过项目都是通过Xib和storyboard实现的,全部改成纯代码实现就相当于要重写项目了,比较懒得我表示无法接受,所以决定保留Xib或storyboard。不过退一步说,加入了sizeClass和约束的xib确实越来越成熟了,对于只适配iOS7之后版本的App确实是更好的选择,但也有一定的缺陷,xib让每个界面都成了特例,很难总结一些共通的方法像基类一样共用,没办法简单化一些模块,那么,该如何解决不便重用的问题呢?
<p>基于自己封装的一套基类一直用的比较顺手,所以我想把纯代码和Xib揉合在一起用,主干逻辑上的一级界面用纯代码,界面里的子视图用Xib,既能有Xib的可视化优点,又能把一些功能模块化方便重用。
自定义带xib的UIView
<p>1.继承UIView创建View类,命名ViewA,
![Uploading 7AE43696-2FEE-4407-B9D6-482D7AADFCAA_727092.png . . .]你会发现继承UIView的时候是不能勾选自动生成Xib的,继续第2步。
<p>2.新建一个Xib,取名ViewA.
小提示:
1.xib中view的 Custom Class必须设置为对应的名称,在这里必须设置成ViewA,乱写是无效的,必须设置为.h.m文件都已经存在的类,不然无效,用loadNib方法也没用。
2.xib中的File's Owner就算设置成ViewA,xib中的view也是无法连接到File's Owner的,因为此时ViewA类和xib中的view都是view,不存在从属关系
3.File's Owner就是类在xib中的表示方式,通过它管理跟xib中视图的关系
<p>3.初始化,下面列出了测试了三种初始化方法以及对应的效果,只有方法三是可以的:
方法一:只有ViewA类中的代码有效,xib无效;
方法二:只有ViewA类中的代码有效,xib无效;
方法三:ViewA类中的代码有效,xib也有效。
结论:ViewA的类和ViewA的xib是同一级别,直接调用类只能有代码中的效果,因为ViewA的类不能自动管理ViewA的xib,而调用xib资源初始化就相当于初始化ViewA,所以也会调用ViewA类中的代码。
<p>方法一
ViewA *viewA = [[ViewA alloc] initWithFrame:CGRectMake(10, 230, 100, 50)];
[self.view addSubview:viewA];
<p>方法二
ViewA *viewB = [[ViewA alloc] init];
viewB.frame = CGRectMake( 120, 230, 100, 50);
[self.view addSubview:viewB];
<p>方法三
ViewA *viewC = [[NSBundle mainBundle] loadNibNamed:@"ViewA" owner:self options:nil][0];
viewC.frame = CGRectMake( 230, 230, 100, 50);
[self.view addSubview:viewC];
小提示:自定义的带xib的UIView,如果其中添加了子视图并且添加了约束,其他视图应用这个自定义视图时,改变它的frame,它里面的子视图会根据约束改变。
自定义带xib的UIViewController
xib是UIView
<p>xib中的视图是UIView时,视图连接至File's Owner 的view,作为UIViewController的view属性。
这种情况下方式一、方式二的初始化方式都可以,建议用方式二,因为,效果一样,还tm代码少。
<p>方式一
ViewControllerA *vcA = [[ViewControllerA alloc] initWithNibName:@"ViewControllerA" bundle:nil];
vcA.view.frame = CGRectMake(10, 10, 200, 100);
[self.view addSubview:vcA.view];
<p>方式二
ViewControllerA *vcB = [[ViewControllerA alloc] init];
vcB.view.frame = CGRectMake(10, 120, 200, 100);
[self.view addSubview:vcB.view];
xib是UIViewController
<p>xib中的视图是UIViewController时,xib中的控制器和类本身是同级,xib中的视图无法再作为UIViewController的view属性。
只能通过以下方式初始化:
ViewControllerB *vcBA = [[NSBundle mainBundle] loadNibNamed:@"ViewControllerB" owner:self options:nil][0];
vcBA.view.frame = CGRectMake(10, 340, 100, 50);
[self.view addSubview:vcBA.view];
总结
<p>逻辑图主干上的界面用纯代码,子视图用xib这种模式还不完全确定。
-
优点
- 主干用纯代码可以调用基类的方法,比如自动在界面超出界面时添加滚动视图并自动调整滚动视图大小,快捷定义导航栏内容等等
- 子视图全部分离出去逻辑会更清晰,各自模块化
-
缺点
- 单独对子视图通过xib自定义,会大量增加类,本来一个试图控制器就能解决的事,用这种方式需要多好多个子视图的类。
- 子视图被单独以类的形式分离出去,只能用纯代码管理子视图之间的交互。
- 主干视图控制的动画不能通过约束实现,只能纯代码控制。约束实现动画点这里