Swift SnapKit和xib自定义view的三种方法以及获取真实frame

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yingBi2014/article/details/80523970

demo下载地址
从xib中加载view,使用的是loadNibNamed方法,这个方法可以写在view的initWithFrame方法里,也可以写在initWithCoder里,也可以自己重新定义一个view的构造方法。我们这里用第三种方法来加载nib文件。

第一种,常用的xib自定义view

首先创建一个纯代码view和一个xib的view,如图,并将xib中的view的clasee定义为testView1,这样就将xib和.swift文件关联起来了。
这里写图片描述
在TestView1中添加加载xib的代码

static func loadView()->TestView1{
        return Bundle.main.loadNibNamed("TestView1", owner: nil, options: nil)?.first as! TestView1
    }

在VC中使用时,代码如下

let testView = TestView1.loadView()
self.view.addSubview(testView)
//这里也可以使用snapKit设置约束
testView.frame = CGRect.init(x: 20, y: 20, width: 100, height: 100)

这种用法很普遍,但是每次自定义后,我们都要自定义一个方法(无论是initWithFrame还是initWithCoder还是loadView),比较麻烦,这里推荐第二种写法,通过协议的方法加载nib中的view。

第二种,通过协议方法款速加载xib中的view

首先创建对应的xib和view文件,如图
这里写图片描述
创建协议文件,NibLoad.swift
协议代码如下

/*
 xib自定义的view遵循这个协议,可以实现快速加载
 */
protocol Nibloadable {

}
extension Nibloadable where Self : UIView{
    static func loadNib(_ nibNmae :String? = nil) -> Self{
        return Bundle.main.loadNibNamed(nibNmae ?? "\(self)", owner: nil, options: nil)?.first as! Self
    }
}

让TestView2遵循Nibloadable协议后就能直接使用了。这样避免了每次自定义view的时候都要自定义加载方法。

testView2 = TestView2.loadNib()
self.view.addSubview(testView2)
testView2.frame = CGRect.init(x: 130, y: 20, width: 100, height: 100)

第三种,使用纯代码SnapKit自定义view

这种一般是通过重写init(frame: CGRect) 方法,在里面添加控件实现自定
义。

四、 纯代码和Xib自定义view时如何获取view的真实frame

如果是纯代码添加约束的话,添加完后,执行setNeedsLayout和layoutIfNeeded,之后,就能获得子控件的真实frame了,

setNeedsLayout:标记一个view为需要更新约束。
layoutIfNeeded:如果有被标记的veiw,执行layoutSubviews,

init?(coder aDecoder: NSCoder):xib初始化控件时调用,在该方法中控件为nil,可以在这个方法里代码添加控件
awakeFromNib() :xib子控件初始化完成后调用,但是frame是xib中的frame,不是真实frame
layoutSubviews() :这个方法里获得的frame是真实的frame

从上面可以看出,如果是xib的话,从layoutSubviews可以获得子控件的真实frame,如果是纯代码的话,添加完约束后,调用setNeedsLayout和layoutIfNeeded后可以获得真实frame。

五、 File’s Owner的理解参考博客

Xib的File’s Owner设置为哪个类,就能在哪个类中连线相应的属性和方法,加载时传入对应的对象,就会执行相应的方法。也就是说,不需要对应view的.swift文件了,只需要一个.xib文件就是一个自定义的view了,该view可以直接拖线到其他的类中。

猜你喜欢

转载自blog.csdn.net/yingBi2014/article/details/80523970