[英]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.