一、解决问题

Xib/Storybarod可以方便、可视化的设置约束,在开发中也越来越重要。由于Xib不能组件化,使得封装、重用都变得不可行。本文将介绍一种解决方案,来实现Xib组件化。

二、模型块原理

在介绍原理之前,我们先弄清楚两个概念:

从上图可以看出,分别选中File's Owner及根视图View,都有Custom Class属性面板。其中Class属性,有什么作用,区别又是什么呢?

2.1 View的Class属性

View的Class属性用于指定选中的视图的实例化类。Xib实际上是一个XML文件,在加载时,解析逻辑会根据XML内容,创建并设置View实例。而此处的Class就是告诉解析逻辑,想要创建什么类的实例。如果此处设置为UIButton,则解析逻辑会生成一个UIButton的实例。

2.2 File's Owner的Class属性

Feile's Owner的Class属性,大部分情况下,都为**UIViewController**及其子类。

1
public func loadNibNamed(name: String!, owner: AnyObject!, options: [NSObject : AnyObject]!) -> [AnyObject]!

从上面xib的加载接口可以看出,加载Xib需要指定一个owner类的**实例**,解析逻辑并没有像**2.1**创建新实例,而是使用参数名为owner的已创建好的实例。

如果没有创建,为什么还要指定File's Owner的Class属性?

此处设置的Class属性值,主要作用是通过关键字@IBOutlet,声明有哪些属性及方法可以建立关联关系。解析逻辑会将关联视图的引用赋值给owner的对应属性,触发事件则执行owner.method()方法。目的为了在owner中,就可以方便的处理界面相关的业务逻辑。可以这样理解,File's Owner的Class,是关联接口声明,loadNibNamed传入的owner是实现。

Tips

File's Owner的Class属性,起一个声明作用,告知哪些属性及方法可以使用。

1
2
3
4
5
6
7
8
class ILViewController: UIViewController {
     @IBOutlet weak var label: UILabel!
}
class ILFlagController: UIViewController {
     
    @IBOutlet weak var label: UILabel!
     
}

既然如此(如上面代码),使用loadNibNamed方法加载Xib时,owner参数传入ILViewController实例,而Xib中File's Owner的Class却设置为ILFlagController,是否可行?答案:可行。

2.4 Xib模块化原理

在Storybarod/Xib中,与组件化有关的只有视图的Class属性。视图是由xib解析逻辑创建,所以要实现组件化,就要在此Class实例化时,自动执行加载子xib模块的功能。

三、工具类源码

为了实现xib的模块化,需要有一个小的功能类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import UIKit
@objc class ILXibView: UIView {
     
    @IBOutlet var contentView: UIView!
     
     
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.loadView()
    }
     
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
     
     
    override func awakeFromNib() {
        super.awakeFromNib()
        self.loadView()
         
    }
     
    private func getXibName() -> String {
        let clzzName = NSStringFromClass(self.classForCoder)
        let nameArray = clzzName.componentsSeparatedByString(".")
        var xibName = nameArray[0]
        if nameArray.count == 2 {
            xibName = nameArray[1]
        }
        return xibName
    }
     
     
    func loadView() {
        if self.contentView != nil {
            return
        }
        self.contentView = self.loadViewWithNibName(self.getXibName(), owner: self)
        self.contentView.frame = self.bounds
        self.contentView.backgroundColor = UIColor.clearColor()
        self.addSubview(self.contentView)
    }
     
    private func loadViewWithNibName(fileName: String, owner: AnyObject) -> UIView {
        let nibs = NSBundle.mainBundle().loadNibNamed(fileName, owner: owner, options: nil)
        return nibs[0] as! UIView
    }
     
     
     
}

四、实战示例

4.1 封装Xib组件

新建ILDemoView.xib、ILDemoView.swift两个文件(文件名要相同),并将ILDemoView文件的File's Owner的Class设置为ILDemoView

1
2
3
4
5
6
7
8
9
class ILDemoView: ILXibView {
    @IBOutlet weak var label: UILabel!
     
    override func awakeFromNib() {
        //一定要调用super
        super.awakeFromNib()
        self.label.text = "你好,中国"
    }
}

在xib文件中添加UILabel,并关联到ILDemoView中

4.2 使用Xib组件

新建Xib/Storyboard文件,添加一个UIView控件,并将此控件的Class属性设置为ILDemoView

Tips

使用的时候,先设置目标UIView的Class属性为ILDemoView,再将此UIView控件拖拽建立关联关系,会发现此时代码中属性类型已自动设置为ILDemoView。ILXibView简单却非常实用,我们项目中已经大量的使用它,对于Xib的模块化封装,绝对是一利器。

下载Demohttp://00red.com/download/Swift之xib模块化设计/ILXibDemo.zip

Swift之xib模块化设计的更多相关文章

  1. Swift - 使用xib添加新界面

    除了使用storyboard外,我们还可以使用xib来设计并创建页面. 1,下面通过一个样例来演示: (1)点击主界面的“信息”按钮,页面切换到信息界面 (2)点击信息界面的“返回”,关闭信息界面,回 ...

  2. iOS程序模块化设计

    一.模块化设计的概述: 模块化设计(Block-based design):对一定范围内的不同功能或相同功能的不同性能.不同规格的产品进行功能分析的基础上,划分并设计出一系列功能模块,通过模块的选择和 ...

  3. PHP--进行模块化设计

    PHP--进行模块化设计 [来源] 达内    [编辑] 达内   [时间]2012-10-30 导航模块可以简单列为一个关于三级页面链接的HTML文件.通常你可以通过用另一种颜色来标明对当前区域的链 ...

  4. 深入浅出百度地图API开发系列(3):模块化设计

    在前面两张简单介绍了百度地图API的基础知识和使用之后,我们来分析一下百度地图API的基本架构,了解一下基本架构可以帮助我们更清晰的了解API的功能和调用过程,也就可以帮助我们在实际开发中可以更方便的 ...

  5. iOS swift使用xib绘制UIView

    目标:用xib绘制一个UIView,在某个ViewController中调用. 三个文件:ViewController.Swift    DemoView.swift     DemoView.xib ...

  6. AngularJs学习笔记7——四大特性之模块化设计

    模块化设计 1.引用自定义模块并调用 自定义模块中,如果有一些服务.封装好笑模块,在另外一个模块中(声明的时候,在依赖列表中加入要引入的模块) var app02 = angular.module(' ...

  7. C51的模块化设计方法

    一个大的单片机程序往往包含很多模块,我是这样组织的: 1.每一个C源文件都要建立一个与之名字一样的H文件(头文件),里面仅仅包括该C文件的函数的声明,其他的什么也不会有,比如变量的定义啊等等不应该有. ...

  8. thinkphp学习笔记5—模块化设计

    原文:thinkphp学习笔记5-模块化设计 1.模块结构 完整的ThinkPHP用用围绕模块/控制器/操作设计,并支持多个入口文件盒多级控制.ThinkPHP默认PATHINFO模式,如下: htt ...

  9. App 组件化/模块化之路——使用SDK的思路进行模块化设计接口

    在不久之前分享一篇<App 组件化/模块化之路——如何封装网络请求框架>文章介绍了我在项目中封装网络请求框架的思路.开发一个 App 会涉及到很多网络请求 API ,例如登录注册接口.用户 ...

随机推荐

  1. 两个对象值相同 (x.equals(y) == true) ,但却可有不同的 hash code ,这 句话对不对

    答:不对,有相同的 hash code这是java语言的定义:1) 对象相等则hashCode一定相等:2) hashCode相等对象未必相等 1.如果是基本变量,没有hashcode和equals方 ...

  2. hadoop 综合大作业

    作业要求来源:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/3339 本次作业是在期中大作业的基础上利用hadoop和hive技术进行 ...

  3. [Beta]第七次 Scrum Meeting

    [Beta]第七次 Scrum Meeting 写在前面 会议时间 会议时长 会议地点 2019/5/17 22:00 10min 大运村公寓6F寝室 附Github仓库:WEDO 例会照片 工作情况 ...

  4. Spring Boot-intellij idea导入方式搭建SpringBoot

    Spring Boot概念 从最根本上来讲,Spring Boot就是一些库的集合,它能够被任意项目的构建系统所使用.简便起见,该框架也提供了命令行界面,它可以用来运行和测试Boot应用.框架的发布版 ...

  5. 函数式接口, Collection等

    Lambda 函数式接口 lambda 表达式的使用需要借助于 函数式接口, 也就是说只有函数式接口才可以将其用 lambda 表达式进行简化. 函数式接口定义为仅含有一个抽象方法的接口. 按照这个定 ...

  6. Python3基础 list clear 清空列表中的内容

             Python : 3.7.3          OS : Ubuntu 18.04.2 LTS         IDE : pycharm-community-2019.1.3    ...

  7. linux系统(centos6)的目录结构

    /bin:bin是Binary的缩写, 这个目录存放着最经常使用的命令. /boot:这里存放的是启动Linux时使用的一些核心文件,包括一些连接文件以及镜像文件. /dev :dev是Device( ...

  8. CSS製作動畫效果(Transition、Animation、Transform)

    CSS 2D Transforms https://www.w3schools.com/css/css3_2dtransforms.asp CSS 3D Transforms https://www. ...

  9. 【VS开发】 Windows平台下管道的使用

    转载地址: 管道分类: 1. 匿名管道: 只能用于相关进程(如父子进程,兄弟进程),并在他们之间建立内存区域,进程终止后,匿名管道也就消失了. 通常用于:重定向子进程的标准输入输出,以便和父进程交换数 ...

  10. 【转帖】处理器史话 | 当Power架构的发展之路遭遇“滑铁卢”

    处理器史话 | 当Power架构的发展之路遭遇“滑铁卢” https://www.eefocus.com/mcu-dsp/366740 (8)Power8:决定了 Power 平台的未来发展 2014 ...