3

Я полный n00b с MacRuby и Cocoa, поэтому имейте это в виду при ответе - мне нужно много деталей и объяснений. :)MacRuby + Interface Builder: как отобразить, затем закрыть, а затем снова отобразить окно

Я создал простой проект, в котором есть два окна, оба из которых построены с помощью Interface Builder. Первое окно представляет собой простой список учетных записей с использованием табличного представления. Он имеет кнопку «+» под таблицей. Когда я нажимаю кнопку +, я хочу показать окно «Добавить новую учетную запись».

У меня также есть класс AccountsController < NSWindowController и класс AddNewAccountController < NSWindowController, настроенный как делегаты для этих окон, с помощью соответствующих способов нажатия кнопки и выходов для ссылки на необходимые окна.

При нажатии на кнопку «+» в окне Учетные записи, у меня есть этот код пожар:

@add_account.center 
    @add_account.display 
    @add_account.makeKeyAndOrderFront(nil) 
    @add_account.orderFrontRegardless 

это прекрасно работает первый раз, когда я нажмите на кнопку +. Все появляется, я могу ввести свои данные и привязать его к моей модели. однако, когда я закрываю новую форму учетной записи, все начинает плохо.

Если я установил новое окно учетной записи, чтобы закрыть его, то во второй раз, когда я нажимаю кнопку +, окно будет всплывать, но оно заморожено. я не могу нажимать на какие-либо кнопки, вводить любые данные или даже закрывать форму. Я предполагаю, что это потому, что код формы был выпущен, поэтому нет обработки цикла обработки формы ... но я не совсем уверен в этом.

Если я установил новое окно учетной записи, которое не будет выпущено при закрытии, то во второй раз, когда я нажму кнопку +, окно появится хорошо, и оно будет полезно - но у него все еще есть все данные, которые я ранее ввел ... он по-прежнему связан с моим предыдущим экземпляром класса Account.

что я делаю неправильно? каков правильный способ создания нового экземпляра формы «Добавить новую учетную запись», создать новую модель учетной записи, привязать эту модель к форме и показать форму, когда я нажимаю кнопку «+» в форме «Аккаунты»?

... это все делается на OSX 10.6.6, 64bit, с XCode 3.2.4

+0

Вы подключили другие элементы к контроллеру (кнопки/текстовые поля)? У меня возникли проблемы с последующими учебными пособиями, в которых выпадающее меню nsobjects отображается в сообщениях диспетчера –

ответ

1

Вопрос заключается в том, что он не создает в окно каждый раз. Release on close - это немного раздражающая опция и обычно используется, только если вы знаете, что оконный контроллер также освобождается, когда окно закрывается. (Заметьте, что я никогда не использовал MacRuby, поэтому я буду давать код в Obj-C, поскольку я знаю, что это правильно, надеюсь, вы можете его преобразовать. Я буду предполагать, что GC включен, как и в MacRuby).

Теперь есть два способа сделать это. Я не совсем уверен, как настроены ваши NIB/классы, поскольку это может быть один из двух способов.

-

Первый способ решить это использование торговых точек, которые вы используете для ссылки на элементы формы заготовки их при отображении окна снова, например, [MyTextField setStringValue: @ «»]. Если вы используете привязки какао, то это немного сложнее, но в основном вы должны убедиться, что связанный объект затуманен. Я бы рекомендовал против привязок, хотя, если вы новичок в Cocoa.

-

Второй способ, чтобы сделать класс AddNewAccountController подкласс NSWindowController. Когда вы нажмете кнопку +, вы затем создадите новый экземпляр и отобразите его (не забудьте сохранить его в ivar).Лучший способ сделать это было бы, как так:

if (!addAccountController) { 
    addAccountController = [[AddNewAccountController alloc] initWithWindowNibName:@"AddNewAccountController"]; 
    [[addAccountController window] setDelegate:self]; 
} 
[addAccountController showWindow:self]; 

Это предотвращает новый экземпляр, вносимый если окно уже видно. Затем необходимо реализовать делегат:

- (void)windowWillClose:(NSNotification *)notification { 
    //If you don't create the account in the AddNewAccountController then do it here 
    addAccountController = nil; 
} 

Очевидно, что вам нужно будет переместить окно в отдельный NIB называется «AddNewAccountController». В этом NIB убедитесь, что класс владельца файла добавлен в AddNewAccountController, а затем подключен к окну окна владельца файла.

Когда все это настроено, вы будете получать свежий контроллер/окно каждый раз. Он также имеет преимущество разделения антенн и контроллеров на более целенаправленные единицы.

Последнее сообщение. В то время как хорошо сделать что-то подобное в окне, вы, возможно, захотите в конце концов посмотреть на это через лист, так как это предотвратит возможность скрытия окна учетной записи добавления за другими окнами.

+0

. Я ничего не вижу в xcode. :) Итак, файл .xib - это NIB, не так ли? Я должен организовать все мои элементы интерфейса, связанные друг с другом в отдельных NIB - окне и меню, контроллерах и других объектах, а не в 1, как сейчас? что даст мне лучший контроль над тем, что загружено, когда ... и все элементы пользовательского интерфейса в NIB создаются при загрузке NIB ... и я мог бы использовать awakeFromNib для создания экземпляра моей модели и привязки ее к datasource окна. это звучит правильно? –

+0

также - окноWillЗакрыть уведомление ... должно ли быть в добавлении нового контроллера учетной записи? или контроллер учетных записей? я бы подумал в контроллере учетных записей, потому что именно там я использую переменную addNewAccountcontroller. но я не вижу, как я могу получить уведомление WindowWillClose из окна AddNewAccount здесь. –

+0

интересное примечание ... я вижу, что вы имеете в виду об использовании ivar, теперь (экземпляр var или @var в рубиновом разговоре). если я использую стандартную переменную, объявленную в методе, который создает экземпляр контроллера, окно будет работать до тех пор, пока оно имеет фокус. как только окно теряет фокус, оно выпадает из области видимости, и сбор мусора разрешает его восстановить, потому что больше нет ссылки на него, а пуф - окно закрывается. : P –