Swift 4 Xib 关联 File's Owner 和 View 的区别

Xib 和 Storyboard 中, 右侧控制面板中都有一个 Custom Class 属性如下图:

Xib: 

图1

Storyboard : 

图 2

Custom Class 中的 Class 选项用来自定义视图或控制器的类型

本文重点介绍 xib 中, 设置 File's owner  的 Custom Class 和 设置 View 的 Custom Class 的区别

关联 File's owner

File's Owner 是一个 Object 控件, 即 storyboard 中那个立方体图形:

图3

上图 Object 控件简介: object 控件为 Interface Builder 中不能直接获取的对象提供一个模板, 你可以将这个 object 实例化为你在 Custom Class 的 Class 中指定类型的实例变量.

也就是说给 xib 中  File's owner  的 Custom Class Class 设置一个类型, 则 File's owner 就是该类型的一个实例

 

关联 File's owner  的  Custom Class

1.直接在 storyboard 中使用, 使用方法参考:

【iOS】Storyboard加载Xib自定义view(Swift)

2.代码中使用, 重写 init 方法, 将 xib 中的 View 拉为约束 contentView 添加在 self :

方法一: 直接在自定义类中获取 View

    @IBOutlet var contentView: UIView!//xib 中的 View 拉为约束 contentView
    @IBOutlet weak var label: UILabel!
    
    //代码创建, 执行此方法, 不执行 init?(coder aDecoder: NSCoder)
    override init(frame: CGRect) {
        super.init(frame: frame)
        awakeFromNib()
    }
    
    //添加在 storyboard 上, 执行此方法
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    
    override func awakeFromNib() {
        super.awakeFromNib()
        setupContentView()
    }
    
    func setupContentView() {
    //owner 一定要为 self, 不能为 nil
        let contentView = Bundle.main.loadNibNamed("CustomView_Fileowner", owner: self, options: nil)?.first as! UIView
        contentView.frame = self.bounds
        contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        addSubview(contentView)
    }
    

方法二: 使用 Swift 的协议, 在协议扩展中获取 View 并添加

protocol NibLoadableProtocol { }

extension NibLoadableProtocol where Self : UIView {
    //设置 File's Owner 的 CustomClass
    //实例方法
    func loadNibFileOwner(_ nibNmae: String? = nil) -> UIView {
        //获取实例的类型
        let object: AnyObject = object_getClass(self)!
        //"\(object)": AntennaParameters.XXXXXX
        //获取真正的类型名
        let className = type(of: object).description().components(separatedBy: ".").last
        
        let contentView = Bundle.main.loadNibNamed(nibNmae ?? className!, owner: self, options: nil)?.first as! UIView
        contentView.frame = self.bounds
        contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        addSubview(contentView)
        return contentView
    }
    
}

//让 CustomView_Fileowner 服从协议
extension CustomView_Fileowner: NibLoadableProtocol { }
    @IBOutlet var contentView: UIView!
    @IBOutlet weak var label: UILabel!
    
    //代码创建, 执行此方法, 不执行 init?(coder aDecoder: NSCoder)
    override init(frame: CGRect) {
        super.init(frame: frame)
        awakeFromNib()
    }
    
    //添加在 storyboard 上, 执行此方法
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    
    override func awakeFromNib() {
        super.awakeFromNib()
        //协议方法
        contentView = loadNibFileOwner()
    }

 

关联 View  的  Custom Class

1.使用类方法

//View 中, 类方法
class func newInstance() -> CustomView_View {
        //owner 为 nil
        return Bundle.main.loadNibNamed("CustomView_View", owner: nil, options: nil)?.first as! CustomView_View
    }


// Controller 中
//使用类型方法创建
let viewView = CustomView_View.newInstance()
viewView.frame = CGRect(x: 50, y: 400, width: 200, height: 100)
view.addSubview(viewView)

2.使用协议扩展

protocol NibLoadableProtocol { }

extension NibLoadableProtocol where Self : UIView {
    
    /*
     static func loadNib(_ nibNmae :String = "") -> Self{
     let nib = nibNmae == "" ? "\(self)" : nibNmae
     return Bundle.main.loadNibNamed(nib, owner: nil, options: nil)?.first as! Self
     }
     */
    //类型方法
    static func loadNib(_ nibNmae: String? = nil) -> Self {
        return Bundle.main.loadNibNamed(nibNmae ?? "\(self)", owner: nil, options: nil)?.first as! Self
    }
}

extension CustomView_View: NibLoadableProtocol { }
//使用协议扩展创建, 类型方法
let viewView = CustomView_View.loadNib()
viewView.frame = CGRect(x: 50, y: 510, width: 200, height: 100)
view.addSubview(viewView)

总结:

关联 File's Owner : 

则 self 是 Custom Class自定义类型的一个实例,  要将 View 拉为约束添加在 self,  可以直接添加在 storyboard 上使用, 在代码中使用时, 要使用对象方法, Bundle.main.loadNibNamed 方法中 owner 为 self

关联 View :

则 self 是 Custom Class自定义类型, 类型不能直接添加在 storyboard, 代码中, 代码中使用时, 要使用类型方法,  Bundle.main.loadNibNamed 方法中 owner 为 nil

猜你喜欢

转载自blog.csdn.net/LeeCSDN77/article/details/82501005
今日推荐