简单介绍
下面的几种用法第一种不推荐虽然简单但是会增加渲染
推荐二,三,四种,我们通过模版的创建可以一步到位。
查看demo ,UIView和Xib文件夹下
基本用法1: Xib 自定义View实例化
class MyClass: UIView {
class func instanceFromNib() -> UIView {
return UINib(nibName:"nib file name", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as UIView
}
}
UIView添加.xib的子视图步骤:
1 创建UIView子类,命名Template。
2 在Interface Builder中创建一个新的.xib文件,并将File's Owner的类设置为Template。
3 在Template类中,通过重写initWithFrame:方法来加载.xib文件,并将其与Template关联起来。
这种做法是在view上面贴一层XIB,有点事简单方便,缺点是多了一层视图。
class Template: UIView {
var contentView: UIView!
override init(frame: CGRect) {
super.init(frame: frame)
contentView = loadXib()
addSubview(contentView)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
func loadXib() -> UIView {
let className = type(of: self)
let bundle = Bundle(for: className)
let name = NSStringFromClass(className).components(separatedBy: ".").last
let nib = UINib(nibName: name!, bundle: bundle)
let view = nib.instantiate(withOwner: self, options: nil).first as! UIView
view.frame = bounds
view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
return view
}
override func layoutSubviews() {
super.layoutSubviews()
}
}
基本用法2: UIView实例方法创建Bundle和view
UIView通过XIB加载步骤
1 创建UIView子类,命名Template。
2 在Interface Builder中创建一个新的.xib文件,并将File's Owner的类设置为Template。
这一步也可以不做,这里为什么这么做的原因是,为了和我们后面自定义模版保持一致。
3 XIB视图的第四个图标(show the identity insepctor)的custom class填写 Template
4 在Template类中,通过重写override func awakeFromNib()方法来加载.xib文件,并将其与Template关联起来。
5 把view视图的size设置成freedom
6 把view视图的Layout 设置为inferred
class Template: UIView {
/// XIB 读取的时候required init可以不写,写的话就会调用
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func awakeFromNib() {
super.awakeFromNib()
}
static func loadFromNib(_ nibname: String? = nil, index: Int = 0) -> Self { // Self(大写)当前类对象
let loadName = nibname == nil ? "\(Self.self)" : nibname!
return Bundle.main.loadNibNamed(loadName, owner: nil, options: nil)![index] as! Self
}
override func layoutSubviews() {
super.layoutSubviews()
}
}
基本用法3: Bundle扩展方法创建Bundle
在用法2的基础上通过协议扩展
1 创建MyXibView:UIView,MyXibView的xib
2 custom class填写MyXibView
3 Bundle扩展方法创建view
4 实现
extension Bundle {
static func loadView<T>(fromNib name: String, withType type: T.Type) -> T {
if let view = Bundle.main.loadNibNamed(name, owner: nil, options: nil)?.first as? T {
return view
}
fatalError("Could not load view with type " + String(describing: type))
}
}
let myxibView:MyXibView = Bundle.loadView(fromNib: "MyXibView", withType: MyXibView.self)
myxibView.frame = CGRectMake(10, distanceTop+430, kScreenWidth-20, 50)
view.addSubview(myxibView)
基本用法4: UIView协议方法创建Bundle和view
在用法2的基础上通过协议扩展
1 创建MyXibView:UIView,MyXibView的xib
2 custom class填写MyXibView
3 添加协议
4 MyXibView遵守协议
5 实现
protocol NibLoadable {
}
/// 加载xib
extension NibLoadable where Self: UIView {
/* Xib 和 类名 同名
* lazy var headerView = HomeHeaderView.loadFromNib()
* Xib 和 类名 不同名
* lazy var sectionView = HomeHeaderView.loadFromNib("sectionView")
* Xib 中多个 View 视图
* lazy var sectionView = Level1SectionView.loadFromNib("Level1HeaderView",index: 1)
* https://www.jianshu.com/p/cceeaaff0397
*/
static func loadFromNib(_ nibname: String? = nil, index: Int = 0) -> Self { // Self(大写)当前类对象
let loadName = nibname == nil ? "\(Self.self)" : nibname!
return Bundle.main.loadNibNamed(loadName, owner: nil, options: nil)![index] as! Self
}
}
class MyXibView: UIView, NibLoadable {
}
let myxibView:MyXibView = MyXibView.loadFromNib()
创建代码模版和XIB模版
第一步: command+shift+G 进入模版文件夹 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates/File Templates/iOS/Source/Cocoa Touch Class.xctemplate
第二步: 目录下创建 UIViewXIBSwift文件夹
第三步:模版复制
找到UIViewSwift文件夹下面的FILEBASENAME.swift文件,拷贝到UIViewXIBSwift文件夹
找到UIViewControllerXIBSwift文件夹下面的FILEBASENAME.xib文件,拷贝到UIViewXIBSwift文件夹

第四步:打开TemplateInfo.plist文件,cocoaTouchSubclass array添加plist字段UIView。
也可以通过系统文本编辑工具打开,cocoaTouchSubclass array中加入<string>UIView</string>

第五步:修改文件模版

第六步:修改XIB模版
删掉outlets 关联

添加文件custom class,和文件关联,和模块关联

把inferred改为fromdom才可以变更尺寸,然后只需要set 相关的 NSLayoutConstraint。

去掉自动适应
当你发现子视图无法添加约束时,进行下图修改
拖动imageview直接在view视图上不会产生这个问题。
拖动imageview和view同级,再拖到view视图会产生。

第六步:完全退出Xcode后,再打开。我们可以一步创建view和对应的xib了
我们会发现初始化代码,和预设xib属性都成功了

模版是根据第二种写法来创建的,当然也可以用Extension或者协议来扩展。个人偏好这一种。
当我们创建一个CustomXIBViewController后再创建一个CustomXIBView的时候,如果没有outlet会崩溃。因为命名问题,CustomXIBView和Controller.view默认关联了但是没有设置关联关系。