如何允许子类使用父类的 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的主要内容,如果未能解决你的问题,请参考以下文章