[英]Determine if `UIView` is loaded from XIB or instantiated from code
我使用以下代碼強制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
視圖,兩者都實現了UILayoutSupport
協議。
當從代碼實例化NibView
子類時,這很好用。 但是,如果視圖是作為故事板中視圖控制器的一部分創建的,則它不起作用 (對於視圖控制器和從XIB文件加載的視圖,可能會發生相同的情況)。
很長一段時間來解釋我的問題的原因: 有沒有辦法讓UIView
知道它是從XIB文件加載,還是可能是該文件的名稱? 或者,否則,實現isRawView()
方法的另一種方法,它應該:
false
true
利用提供的init
函數。
init(frame:)
- >來自代碼 init(coder:)
- >來自筆尖 示例代碼:
override init(frame: CGRect) {
super.init(frame: frame)
print("From code")
}
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
print("From nib")
}
我可以像這樣打印出類名:
print(NSStringFromClass(type(of: self)).components(separatedBy: ".").last ?? "Couldn't get it")
你應該可以使用它,也許稍作調整,以獲得你需要的東西。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.