Я ищу полезную практику инициализации подпредставлений (например, текста меток или кнопок) пользовательского представления, которые подключены через IBOutlets.
Контроллер представления пользовательского представления вызывает файл 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
}
}
}
}
}
Инициализация контроллера представления вызывается из модуля презентатора другого контроллера представления очень классным способом:
let view = MenuHeaderItemView()
Однако после инициализации контроллера представления, какОжидается, IBOutlets найдены ноль.Тем не менее, я хотел установить строковое значение labelStatus
сразу после инициализации представления (например, стандартной строки) через NSBundle
(или Bundle
) loadNibName
без ожидания awakeFromNib
.
Какова хорошая практика или подход, позволяющий делать это синхронно и получать доступ к IBOutlets сразу после инициализации?
РЕДАКТИРОВАТЬ: Я понял, что labelStatus
и stackList
успешнозагружено в contentView
: Есть ли какой-нибудь элегантный способ скопировать их содержимое / создание экземпляров в IBOutlets?