簡體   English   中英

從Swift 4中的XIB實例化時,自定義UIView為空白

[英]Custom UIView is blank when instantiated from a XIB in Swift 4

我有一個試圖從自定義XIB加載的自定義視圖,但是加載后該視圖似乎是空白的,甚至認為調試時它的大小正確。

我的調試語句顯示框架具有正確的大小:

commonInit()
XIB:MyCustomView
myView框架:(0.0、0.0、320.0、568.0)
myView ContentSize:(320.0,710.0)

這是我用來調用“自定義視圖”的自定義VC

class MyCustomViewController: UIViewController {

    var myView : MyCustomView!

    override func viewDidLoad() {
        super.viewDidLoad()

        myView = MyCustomView(frame: self.view.frame)

        self.view.addSubview(myView)

        updateScrollViewSize()

        print("myView Frame: \(myView.frame)")
        print("myView ContentSize: \(myView.contentView.contentSize)")

    }

    func updateScrollViewSize () {
        var contentRect = CGRect.zero
        for view in myView.contentView.subviews {
            contentRect = contentRect.union(view.frame)
        }
        myView.contentView.contentSize = CGSize(width: myView.contentView.frame.size.width, height: contentRect.size.height + 5)
    }
}

有一個XIB ,其文件所有者為MyCustomView,並且所有插座均已正確連接。

class MyCustomView: UIView {

     let kCONTENT_XIB_NAME = "MyCustomView"

    @IBOutlet var contentView: UIScrollView!

    @IBOutlet weak var lbl_datein: UILabel!
    //.. A bunch of other GUI elements for the scrollview
    @IBOutlet weak var text_location: UITextField!


    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }

    func commonInit() {
        print(#function)
        print("XIB: \(kCONTENT_XIB_NAME)")

        Bundle.main.loadNibNamed(kCONTENT_XIB_NAME, owner: self, options: nil)
        contentView.addSubview(self)
        contentView.frame = self.bounds
        contentView.backgroundColor = .blue
    }
}

有人在嘗試加載視圖時是否看到我做錯了什么

我將使用擴展程序發布您所做的替代方案。

extension UIView {

    @discardableResult
    func fromNib<T : UIView>(_ nibName: String? = nil) -> T? {
        let bundle = Bundle(for: type(of: self))
        guard let view = bundle.loadNibNamed(nibName ?? String(describing: type(of: self)), owner: self, options: nil)?[0] as? T else {
            return nil
        }
        view.translatesAutoresizingMaskIntoConstraints = false

        self.addSubview(view)
        view.autoPinEdgesToSuperviewEdges()
        return view
    }
}

*請注意,我正在使用PureLayout進行方便的自動布局管理,即使您不使用PureLayout,也可以自己手動應用約束。

使用以上所有操作,您只需從init調用以下內容;

fromNib()

*最后的筆記。 自定義視圖名稱必須與筆尖名稱匹配,否則,您必須從nib函數將筆尖名稱傳遞給您。

您現在有了更多可重用的東西。

我無法獲取此代碼來運行復制/粘貼代碼。 也許缺少一些設置,但是我很難理解它應該如何工作。 問題中的原始代碼在此行崩潰:

contentView.addSubview(self)

因為當您擁有IBOutlets ,如果使用MyCustomView(frame: self.view.frame)對其進行初始化,則它們將始終為nil 它必須調用initWithCoder函數。

這里有很多事情,但這就是我要做的:

class MyCustomViewController: UIViewController {

    var myView: MyCustomView!

    override func viewDidLoad() {
        super.viewDidLoad()

        myView = Bundle.main.loadNibNamed("MyCustomView", owner: self, options: nil)?.first as? MyCustomView

        self.view.addSubview(myView)

        updateScrollViewSize()

        print("myView Frame: \(myView.frame)")
        print("myView ContentSize: \(myView.contentView.contentSize)")

    }

    func updateScrollViewSize () {
        var contentRect = CGRect.zero
        for view in myView.contentView.subviews {
            contentRect = contentRect.union(view.frame)
        }
        myView.contentView.contentSize = CGSize(width: myView.contentView.frame.size.width, height: contentRect.size.height + 5)
    }

}

class MyCustomView: UIView {

    let kCONTENT_XIB_NAME = "MyCustomView"

    @IBOutlet var contentView: UIScrollView!

    @IBOutlet weak var lbl_datein: UILabel!
    //.. A bunch of other GUI elements for the scrollview
    @IBOutlet weak var text_location: UITextField!

}

我假設筆尖中的頂級對象是MyCustomView類,這將導致很多奇怪的事情。 loadNibNamed將調用init?(coder aDecoder: NSCoder) ,因此理想情況下,您首先只是從視圖控制器而不是自定義視圖對象調用它。

關於“無法將自己添加為子視圖”錯誤,我在運行時沒有看到該錯誤,但我希望從此行可以看到它:

contentView.addSubview(self)

因為這正是它,加入self因為這是已經是一個子視圖視圖的子視圖self

如果我的替代答案太多,請讓我嘗試解決您現有的問題。 代替下面的內容;

Bundle.main.loadNibNamed(kCONTENT_XIB_NAME, owner: self, options: nil)
contentView.addSubview(self)

嘗試;

let nibView = Bundle.main.loadNibNamed(kCONTENT_XIB_NAME, owner: self, options: nil)
self.addSubView(nibView)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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