簡體   English   中英

確定是從UIB加載`UIView`還是從代碼實例化

[英]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()方法的另一種方法,它應該:

  • 如果視圖已從關聯的XIB文件(其名稱是類名)反序列化,則返回false
  • 否則返回true

利用提供的init函數。

示例代碼:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM