我有一个试图从自定义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
}
}
有人在尝试加载视图时看到我做错了什么吗
答案 0 :(得分:0)
我将使用扩展程序发布您所做的替代选择。
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函数将笔尖名称传递给您。
您现在有了更多可重用的东西。
答案 1 :(得分:0)
我无法获取它来运行复制/粘贴代码。也许缺少一些设置,但是我很难理解它应该如何工作。问题中的原始代码在此行崩溃:
contentView.addSubview(self)
因为当您拥有IBOutlets
时,如果您使用nil
进行初始化,它们将始终为MyCustomView(frame: self.view.frame)
。它必须调用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
子视图的视图的子视图。
答案 2 :(得分:0)
如果我的替代答案太多,请让我尝试解决您现有的问题。代替下面的内容;
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)