一. 需要在xib或者storyboard中嵌套使用
1. 例如定义AView
,新建AView.swift
、AView.xib
**3个要点**
-
xib
中view
的custom class
不设置,File's Owner
的设置为AView
此时xib
可以拖控件、添加约束、拖线IBOutlet
到AView.swift
-
AView.swift
加载xib
的方式
调用方法extXibLoadNib()
(结尾有实现方法) -
AView
中的IBOutlet
为是强引用
import UIKit
@IBDesignable
class AView: UIView, NibLoadable {
@IBOutlet var ivIcon: UIImageView!
@IBOutlet var lbName: UILabel!
@IBOutlet var lbContent: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
///让控件不随着父控件的拉伸而拉伸
autoresizingMask = UIView.AutoresizingMask()
extXibLoadNib()
}
}
2.使用
xib
或者storyboard
中添加view
,将view
的custom class
设置为AView
,设置约束即可。
二. 普通使用
-
xib
中view
的custom class
设置为AView
,File's Owner
的不设置 -
AView.swift
加载xib
的方式
遵守协议NibLoadable
import UIKit
@IBDesignable
class AView: UIView, NibLoadable {
@IBOutlet var lbName: UILabel!
//
// MARK: - AView.xib中 view的class设置为AView
//
override func awakeFromNib() {
super.awakeFromNib()
///让控件不随着父控件的拉伸而拉伸
autoresizingMask = UIView.AutoresizingMask()
}
}
- 使用
AView
fileprivate func loadAView() {
let vA = AView.loadUseXibName()
vA.frame = CGRect(x: 220, y: 300, width: 100, height: 40)
vA.backgroundColor = .systemOrange
vA.lbName.text = "A 220"
view.addSuAView(vClassFun)
}
更新:
-
AView
的IBOutlet
都用强引用 - 获取类名的扩展
extension NSObject {
///类名
var clsName: String {
get {
let desc = type(of: self).description()
if let name = desc.components(separatedBy: ".").last {
return name
}
return desc
}
}
}
- 加载
xib
的扩展
-
xib
嵌套xib
extension UIView {
func extXibLoadNib(index: Int) -> UIView {
let bundle = Bundle(for: type(of: self))
let nib = UINib(nibName: self.clsName, bundle: bundle)
///vBg的大小是xib中的大小
let vBg = (nib.instantiate(withOwner: self, options: nil)[index]) as! UIView
///bounds是sb中拖的view的大小
///po self <ABC.CollectBottomView: frame = (0 812; 414 50);
vBg.frame = bounds
///vBg的实际大小需要调整
addSubview(vBg)
return vBg
}
/*
需要在xib或者storyboard中嵌套使用的xib加载
- xib的class 未设置类名
- xib的File's Owner设置为类名
可不用返回vBg
使用:
xib或者storyboard中添加view,将view的custom class设置为AView,
将view托线IBOutlet到控制器中再设置其frame等,即可使用view的控件
*/
@discardableResult
func extXibLoadNib() -> UIView {
let bundle = Bundle(for: type(of: self))
let nib = UINib(nibName: self.clsName, bundle: bundle)
///vBg的大小是xib中的大小
guard let vBg = (nib.instantiate(withOwner: self, options: nil)[0]) as? UIView else { return UIView() }
vBg.frame = bounds
///vBg的实际大小需要调整
addSubview(vBg)
return vBg
}
}
- 类方法普通加载
xib
,该view
继承协议NibLoadable
protocol NibLoadable {
}
/*
//3.1 xib文件与类名同名的情况
let demoView = DemoView.loadFromNib()
demoView.backgroundColor = UIColor.red
view.addSubview(demoView)
//3.2 xib文件与类名不相同的情况
let testV = TestView.loadFromNib("TestView0")
testV.backgroundColor = UIColor.green
view.addSubview(testV)
*/
extension NibLoadable where Self : UIView {
//在协议里面不允许定义class 只能定义static
static func loadUseXibName(_ nibname: String? = nil) -> Self {//Self (大写) 当前类对象
//self(小写) 当前对象
let loadName = nibname == nil ? "\(self)" : nibname!
return Bundle.main.loadNibNamed(loadName, owner: nil, options: nil)?.first as! Self
}
//在协议里面不允许定义class 只能定义static
static func loadUseNibName(_ nibname: String? = nil) -> Self {//Self (大写) 当前类对象
//self(小写) 当前对象
let loadName = nibname == nil ? "\(self)" : nibname!
let nib = UINib.init(nibName: loadName, bundle: nil)
let v = nib.instantiate(withOwner: nil, options: nil)[0] as! Self
return v
}
}
网友评论