我正在寻找如何初始化通过IBOutlet连接的自定义视图的子视图(例如标签或按钮的文本)的良好实践。
定制视图的视图控制器正在init上调用xib文件,如下所示:
final class MenuDiscoveryListView : NSView, MenuDiscoveryListViewProtocol {
let C_NAME_XIB = "MenuDiscoveryList"
@IBOutlet weak var labelStatus: NSTextField!
@IBOutlet weak var stackList: NSStackView!
var presenter : MenuDiscoveryListPresenter?
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
xibInit(autoXibLoading: true)
}
required init?(coder decoder: NSCoder) {
super.init(coder: decoder)
xibInit(autoXibLoading: false)
}
/// Routine for initializating view
///
/// - Parameter loadXib: Select if auto-load from related xib file into the view container is desired. Select TRUE, if function is called from NSView's `init(frame frameRect: NSRect)`.
func xibInit(autoXibLoading loadXib : Bool = true) {
// Load xib item
if loadXib {
var topLevelObjects : NSArray?
if Bundle(for: type(of: self)).loadNibNamed(C_NAME_XIB, owner: self, topLevelObjects: &topLevelObjects) {
if let contentView = topLevelObjects!.first(where: { $0 is NSView }) as? NSView {
// Add loaded view from xib file into container as subview
self.addSubview(contentView)
// Transfer dimensions
self.frame = contentView.frame
// Define constraints
self.translatesAutoresizingMaskIntoConstraints = false
contentView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint(item: self, attribute: .leading, relatedBy: .equal, toItem: contentView, attribute: .leading, multiplier: 1.0, constant: 0).isActive = true
NSLayoutConstraint(item: self, attribute: .trailing, relatedBy: .equal, toItem: contentView, attribute: .trailing, multiplier: 1.0, constant: 0).isActive = true
NSLayoutConstraint(item: self, attribute: .top, relatedBy: .equal, toItem: contentView, attribute: .top, multiplier: 1.0, constant: 0).isActive = true
NSLayoutConstraint(item: self, attribute: .bottom, relatedBy: .equal, toItem: contentView, attribute: .bottom, multiplier: 1.0, constant: 0).isActive = true
}
}
}
}
}
视图控制器的init以非常经典的方式从另一个视图控制器的presenter模块调用:
let view = MenuHeaderItemView()
但是,在按预期方式初始化视图控制器之后,IBOutlets发现为零。但是,我想在通过
labelStatus
(或NSBundle
的)Bundle
初始化视图(例如标准字符串)后立即设置字符串值loadNibName
,而不必等待awakeFromNib
。有什么好的做法或方法来同步执行此操作并在初始化之后立即访问IBOutlets?
编辑:
我已经意识到
labelStatus
和stackList
已成功加载到contentView
中:有什么优雅的方法可以将其内容/实例复制到IBOutlets?
最佳答案
与声明
让视图= MenuHeaderItemView()
视图控制器尚未加载其视图层次/子视图。
据我了解,您可以使用:
let customView = Bundle.main.loadNibNamed("MenuDiscoveryList", owner: nil,
options: nil)?[0] as? MenuDiscoveryListView
if let menuView = customView {
menuView.labelStatus.text = "You label string"
}
谢谢,尝试一下。