自定義view的加載方式有loadNibNamed或者nib.instantiate可是這些都不能使xib直接在storyboard上直接使用。git
本文分享出能夠在storyboard上直接把xib顯示出來,也能夠直接用代碼加載出來的技能。接下來放大招啦!github
1. 新建一個UIview,再建一個xib與之名稱對應。swift
2. 綁定xib的File's Owner 的class,注意不是選中View,而是File's Owner。ide
3. 在view中開始代碼初始化以下:ui
override init(frame: CGRect) {3d
super.init(frame: frame)code
initFromXib()component
}blog
required init?(coder aDecoder: NSCoder) {繼承
super.init(coder: aDecoder)
initFromXib()
}
func initFromXib() {
let myclass = type(of: self)
let bundle = Bundle(for: myclass)
let name = NSStringFromClass(myclass).components(separatedBy: ".").last
let nib = UINib(nibName: name!, bundle: bundle)
self.contentView = nib.instantiate(withOwner: self, options: nil)[0] as! UIView
self.contentView.frame = bounds
self.addSubview(contentView)
}
每次都要這樣寫是否是有點麻煩呢?
擴展一個協議NibLoadable,把initFromXib()裏面的這段放在協議裏。像這樣
extension Nibloadable where Self : UIView {
static func loadNibView(className: Self) -> UIView {
let myclass = type(of: className)
let bundle = Bundle(for: myclass)
let name = NSStringFromClass(myclass).components(separatedBy: ".").last
let nib = UINib(nibName: name!, bundle: bundle)
return nib.instantiate(withOwner: className, options: nil)[0] as! UIView
}
}
那麼initFromXib()就變成這樣,是否是更簡化了也用上了swift的協議
func initFromXib() {
self.contentView = CustomXibView.loadNibView(className: self)
self.contentView.frame = bounds
self.addSubview(contentView)
}
然而還不夠,這些沒次建立view都須要重複寫,在加上@IBInspectable的屬性就更多,不行我還想簡化。繼承思想來一波,寫一個基礎View把全部的屬性都寫在這裏以及初始化方法也都寫在這裏。自定義view繼承它,只須要對外提供一個model變量,來設置內容更改就行。
// 基礎view
@IBDesignable
class CGBaseView: UIView, Nibloadable
// 這裏是自定義view部分
class TestXibView: CGBaseView {
var model: [String: String]? {
didSet {
desL.text = model?["des"]
}
}
看文章還不夠詳細,那來開代碼吧!附上github地址:https://github.com/caoge9/CG_CustomXibView.git