swift storyboard中使用xib定义的view

2020-03-04  本文已影响0人  喵喵粉

一. 需要在xib或者storyboard中嵌套使用

1. 例如定义AView,新建AView.swiftAView.xib

**3个要点**

image.png

此时xib可以拖控件、添加约束、拖线IBOutletAView.swift

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,将viewcustom class设置为AView,设置约束即可。


二. 普通使用

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()
    }
}
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)
}

更新:

  1. AViewIBOutlet都用强引用
  2. 获取类名的扩展
extension NSObject {
    
    ///类名
    var clsName: String {
        get {
            let desc = type(of: self).description()
            
            if let name = desc.components(separatedBy: ".").last {
                return name
            }
            
            return desc
        }
    }
}
  1. 加载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
    }
}
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
    }
}
上一篇下一篇

猜你喜欢

热点阅读