如何允许子类使用父类的 nib

Posted

技术标签:

【中文标题】如何允许子类使用父类的 nib【英文标题】:How to allow subclasses to use parent class's nib 【发布时间】:2018-02-09 21:56:47 【问题描述】:

假设我有一个父视图类,它至少包含 1 个属性:

  class BaseView : UIView 
    @IBOutlet weak var myLabel: UILabel!
   

这个类有一个对应的 xib 文件,其中有一个从 xib 到 myLabel 属性的出口连接。

现在假设我们还有一些继承自这个类的子类:

  class ChildView : BaseView 
     func setup() 
  

ChildView 有一些自定义逻辑,但可以重用 BaseView 中的所有视图。它没有(或者我宁愿避免它拥有)自己的相应 xib 文件。

我希望能够做这样的事情:

  let childView = Bundle.main.loadNibNamed(String(describing: BaseView.self), owner: nil, options:nil)?.first as! ChildViewA

但这不起作用。也没有:

  let childView = ChildView()
  Bundle.main.loadNibNamed(String(describing: BaseView.self owner: childView, options: nil)

是否允许子视图以类似的方式从其父视图的 xib 文件继承?

【问题讨论】:

你想使用两个类的同一个xib文件吗? 是的,尽管只有第二个类继承自第一个类的关系。 xib文件中没有继承的概念。您可以使用继承的类,但不能使用 xib。 【参考方案1】:

问题在于 nib 中的根视图的类型为 BaseView,因此 as! ChildViewA 失败。由于您无权访问 nib 加载器用来解压缩 xib 的 NSKeyedUnarchiver,因此在解压缩期间没有简单的方法来替换您自己的类。

这里有一个解决方法。

不要不要BaseView本身嵌入到xib中。相反,将 xib 中的***视图设为纯 UIView,并将 File's Owner 自定义类设置为 BaseView。然后删除与顶层视图的所有连接,并将它们设置为文件所有者。还要给BaseView 一个rootViewFromNib 插座,并将其连接到根视图。

然后,给BaseView 一个初始化器,它加载它的 nib 并将rootViewFromNib 作为子视图添加到自身,其框架固定到BaseView 自己的bounds。您可以使用自动调整大小来做到这一点。

最后,BaseView 应该是这样的:

class BaseView: UIView 

    @IBOutlet var myLabel: UILabel!
    // other outlets, etc.

    @IBOutlet private var rootViewFromNib: UIView!

    override init(frame: CGRect) 
        super.init(frame: frame)

        Bundle(for: BaseView.self).loadNibNamed("BaseView", owner: self, options: nil)
        rootViewFromNib.frame = bounds
        rootViewFromNib.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        rootViewFromNib.translatesAutoresizingMaskIntoConstraints = true
        addSubview(rootViewFromNib)
    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    


BaseView.xib 应该是这样的:

【讨论】:

以上是关于如何允许子类使用父类的 nib的主要内容,如果未能解决你的问题,请参考以下文章

如何在java中子类中父类的对象如何调用父类的方法?

C++子类如何调父类的虚函数

C#中子类构造函数中如何调用父类构造函数

Java—多态

第7章 继承

如何在不使用 Nib 的情况下实例化和调用 UIView 子类