问题-如何自定义带Xib的UIView

前言

最近要重构公司的几个项目,不过项目都是通过Xib和storyboard实现的,全部改成纯代码实现就相当于要重写项目了,比较懒得我表示无法接受,所以决定保留Xib或storyboard。不过退一步说,加入了sizeClass和约束的xib确实越来越成熟了,对于只适配iOS7之后版本的App确实是更好的选择,但也有一定的缺陷,xib让每个界面都成了特例,很难总结一些共通的方法像基类一样共用,没办法简单化一些模块,那么,该如何解决不便重用的问题呢?

基于自己封装的一套基类一直用的比较顺手,所以我想把纯代码和Xib揉合在一起用,主干逻辑上的一级界面用纯代码,界面里的子视图用Xib,既能有Xib的可视化优点,又能把一些功能模块化方便重用。


自定义带xib的UIView

1.继承UIView创建View类,命名ViewA,
![Uploading 7AE43696-2FEE-4407-B9D6-482D7AADFCAA_727092.png . . .]你会发现继承UIView的时候是不能勾选自动生成Xib的,继续第2步。

2.新建一个Xib,取名ViewA.

问题-如何自定义带Xib的UIView_第1张图片
新建Xib

小提示:
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中视图的关系

问题-如何自定义带Xib的UIView_第2张图片
7AE43696-2FEE-4407-B9D6-482D7AADFCAA.png

3.初始化,下面列出了测试了三种初始化方法以及对应的效果,只有方法三是可以的:
方法一:只有ViewA类中的代码有效,xib无效;
方法二:只有ViewA类中的代码有效,xib无效;
方法三:ViewA类中的代码有效,xib也有效。
结论:ViewA的类和ViewA的xib是同一级别,直接调用类只能有代码中的效果,因为ViewA的类不能自动管理ViewA的xib,而调用xib资源初始化就相当于初始化ViewA,所以也会调用ViewA类中的代码。

方法一

   ViewA *viewA = [[ViewA alloc] initWithFrame:CGRectMake(10, 230, 100, 50)];
   [self.view addSubview:viewA];

方法二

   ViewA *viewB = [[ViewA alloc] init];
   viewB.frame = CGRectMake( 120, 230, 100, 50);
   [self.view addSubview:viewB];

方法三

   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

xib中的视图是UIView时,视图连接至File's Owner 的view,作为UIViewController的view属性。
这种情况下方式一、方式二的初始化方式都可以,建议用方式二,因为,效果一样,还tm代码少。

方式一

    ViewControllerA *vcA = [[ViewControllerA alloc] initWithNibName:@"ViewControllerA" bundle:nil];
    vcA.view.frame = CGRectMake(10, 10, 200, 100);
    [self.view addSubview:vcA.view];

方式二

    ViewControllerA *vcB = [[ViewControllerA alloc] init];
    vcB.view.frame = CGRectMake(10, 120, 200, 100);
    [self.view addSubview:vcB.view];
xib是UIViewController

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];

总结

逻辑图主干上的界面用纯代码,子视图用xib这种模式还不完全确定。

  • 优点

    • 主干用纯代码可以调用基类的方法,比如自动在界面超出界面时添加滚动视图并自动调整滚动视图大小,快捷定义导航栏内容等等
    • 子视图全部分离出去逻辑会更清晰,各自模块化
  • 缺点

    • 单独对子视图通过xib自定义,会大量增加类,本来一个试图控制器就能解决的事,用这种方式需要多好多个子视图的类。
    • 子视图被单独以类的形式分离出去,只能用纯代码管理子视图之间的交互。
    • 主干视图控制的动画不能通过约束实现,只能纯代码控制。约束实现动画点这里

你可能感兴趣的:(问题-如何自定义带Xib的UIView)