2013-04-09 1 views
0

Я пишу пользовательский элемент управления пользовательского интерфейса и интересуюсь стандартными практиками, связанными с инициализацией (особенно в зависимости от делегата элемента управления). Как и большинство элементов управления, мой элемент управления полагается на делегата, чтобы предоставить важную информацию о том, как сделать сам.Инициализация пользовательского контроля как программно, так и от NIB

Когда элемент управления используется в пределах NIB, методы корректно вызывают методы initWithCoder: и awakeFromNib, и делегат прекрасно настроен через IBOutlet. awakeFromNib вызывает вторичный метод, называемый setupControl, который взаимодействует с делегатом для настройки моего элемента управления. Жизнь прекрасна!

Однако, когда я создаю элемент управления вручную, используя initWithFrame:, очевидно, awakeFromNib никогда не вызывается. Мне любопытно, как другие разработчики занимаются поддержкой как IB, так и программного управления. Я вижу несколько методов для поддержки программного дела:

  • Force разработчика позвонить initWithFrame:, а затем setDelegate:, а затем setupControl. Не слишком обременительны, но выставляют внутреннюю работу моего контроля (т. Е. Они должны знать о setupControl)
  • Измените способ принятия делегата initWithFrame:. Это немного инкапсулирует внутреннюю работу, но я не уверен, что это особенно часто используемая идиома (и кажется, что манипулирование подзонами на основе ответов делегатов - это то, что обычно откладывается до тех пор, пока бит в жизненном цикле представления не будет, а не в инициализаторе)
  • Переопределите аксессуар setDelegate: для вызова метода setupControl. Это не большой поклонник этого, так как он отвлекает программирование от побочного эффекта.

Просто подумал, что я брошу его туда, чтобы узнать, какие техники я упустил. Мысли?

Спасибо. Крейг

ответ

0

Первый: -awakeFromNib автоматически отправляется на элементы управления после полной загрузки NIB. Это означает, что после того, как весь пользовательский интерфейс, инкапсулированный в NIB, будет загружен Cocoa, отправьте -awakeFromNib всем компонентам пользовательского интерфейса. Единственная причина, по которой он отправляется после загрузки, - это избежать nil IBOutlet. Нормальный, если вы добавляете элементы управления программно, это делается после распаковки NIB и после загрузки всех элементов пользовательского интерфейса (при условии, что вы подключаете IBOutlet к настраиваемому элементу управления). Таким образом, нет никакой потенциальной проблемы, вызывающей -awakeFromNib в конце вашего метода -initWithFrame:.

И: Все ожидают вызова -setDelegate: при программном программировании. -initWithFrame: + -setDelegate: не так много, чтобы получить функциональный контроль, созданный, я думаю;)

+0

Однако, когда вы говорите, что нет проблемы с вызовом 'awakeFromNib' из' initWithFrame: ', в программном мире делегат выиграл ' t устанавливается через 'IBOutlet'. Он будет установлен вручную в коде - это нормально, но это произойдет ** после вызова 'initWithFrame:', что будет означать, что 'initWithFrame:' ​​не может надежно называть 'awakeFromNib', потому что он полагается на делегат будучи установленным. Это дилемма курицы/яйца, с которой я борюсь. –

+0

Насколько я понимаю, ваш контроль зависит от его делегата на этапе инициализации и настройки? Делегат является необязательным и не может потребоваться для инициализации чего-либо. Здесь у вас проблема с дизайном. – Pyroh