美文网首页
问题-如何自定义带Xib的UIView

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

作者: 才寒 | 来源:发表于2016-03-16 09:32 被阅读3659次

    前言

    <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.

    新建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中视图的关系

    7AE43696-2FEE-4407-B9D6-482D7AADFCAA.png

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

    相关文章

      网友评论

          本文标题:问题-如何自定义带Xib的UIView

          本文链接:https://www.haomeiwen.com/subject/bzcqlttx.html