【发布时间】:2017-04-03 13:48:13
【问题描述】:
我使用以下代码强制UIView 的子类从名称为实际类名的 XIB 文件中加载:
class NibView : UIView {
override func awakeAfter(using aDecoder: NSCoder) -> Any? {
guard isRawView() else { return self }
for view in self.subviews {
view.removeFromSuperview()
}
let view = instanceFromNib()
return view
}
func isRawView() -> Bool {
// What here?
}
}
isRawView() 方法的目的是确定这个视图是从代码创建的,还是从相应的 XIB 文件加载的。
到目前为止我使用的实现是:
func isRawView() -> Bool {
// A subview created by code (as opposed to being deserialized from a nib)
// has 2 subviews, both implementing the `UILayerSupport` protocol
return
self.subviews.count == 2 &&
self.subviews.flatMap(
{ $0.conforms(to: UILayoutSupport.self) ? $0 : nil }).count == 2
}
它使用一种技巧来确定视图是否是从代码创建的,因为在这种情况下它正好包含 2 个子视图,都实现了UILayoutSupport 协议。
当NibView 子类从代码中实例化时,这很有效。但是如果视图是作为情节提要中视图控制器的一部分创建的,则它不起作用(并且可能同样适用于视图控制器和从 XIB 文件加载的视图)。
长篇大论来解释我的问题的原因:有没有办法让UIView 知道它是否是从 XIB 文件加载的,并且可能是该文件的名称? 或者,否则,实现isRawView() 方法的另一种方法应该是:
- 如果视图已从关联的 XIB 文件(其名称是类名)反序列化,则返回
false - 否则返回
true
【问题讨论】: