3

私はMacRubyとCocoaの完全なn00bですので、答えるときはそのことを覚えておいてください。 :)MacRuby + Interface Builder:ウィンドウを表示して閉じてから再び表示する方法

2つのウィンドウがあり、どちらもInterface Builderで構築された単純なプロジェクトをセットアップしました。最初のウィンドウは、テーブルビューを使用するアカウントの単純なリストです。テーブルの下に "+"ボタンがあります。 +ボタンをクリックすると、「新しいアカウントの追加」ウィンドウが表示されます。

AccountsController < NSWindowControllerAddNewAccountController < NSWindowControllerクラスもあり、これらのウィンドウの代理人として設定され、適切なボタンクリックメソッドが組み込まれていて、必要なウィンドウを参照するコンセントがあります。これが最初の時間を素晴らしい作品

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

私は+ボタンをクリックしてください:私はアカウントのウィンドウ内の「+」ボタンをクリックすると

は、私はこのコードの火を持っています。すべてが表示され、データを入力してモデルにバインドすることができます。しかし、私が新しいアカウントのフォームを閉じると、状況が悪くなり始めます。

新しいアカウントの追加ウィンドウを閉じると設定した場合、もう一度+ボタンをクリックするとウィンドウはポップアップしますが、フリーズします。ボタンをクリックしたり、データを入力したり、フォームを閉じたりすることはできません。私はこれがフォームのコードがリリースされているので、フォームを処理しているメッセージループがないと仮定します...しかし、私はこれについて完全にはわかりません。

新しいアカウントの追加ウィンドウを閉じるときに解放しないで、もう一度+ボタンをクリックすると、ウィンドウが表示され、使用可能になります - しかし、以前入力したすべてのデータ...それは私の以前のAccountクラスのインスタンスにバインドされています。

何が間違っていますか?アカウントのフォームで+ボタンをクリックすると、新しいアカウントの追加フォームの新しいインスタンスを作成し、新しいアカウントのモデルを作成し、そのモデルをフォームにバインドしてフォームを表示する正しい方法は何ですか?

...これはOSX 10.6.6、64ビットで行われているすべての、XCodeの3.2.4と

+0

コントローラ(ボタン/テキストエリア)に他の要素を接続しましたか?私はコントローラのメッセージにnsobjectsドロップダウンメニューを表示するチュートリアルに続いて問題が発生しました –

答えて

1

問題は、それが窓を毎回作成していないということです。クローズ時のリリースはちょっと面倒なオプションですが、ウィンドウが閉じたときにウィンドウコントローラもリリースされていることが分かっている場合にのみ一般的に使用されます。 (MacRubyを使ったことは一度もありませんでしたので、Obj-Cでコードを記述していますが、正しいと思いますが、うまくいけば変換することができます。

これを行うには2通りの方法があります。あなたのNIB /クラスが2つの方法のうちの1つになる可能性があるので、どのように設定されているかは完全にはわかりません。

-

それを解決するための最初の方法は、あなたが再び例えばウィンドウを表示するときに[する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; 
} 

あなたが「AddNewAccountController」と呼ばれる別のNIBにウィンドウを移動する必要があります。このNIBでは、File's OwnerのクラスをAddNewAccountControllerに設定してから、File's Ownerのウィンドウアウトレットをウィンドウに接続するようにしてください。

これをすべて設定すると、毎回新しいコントローラ/ウィンドウが表示されます。また、ニブやコントローラーをより重視されるユニットに分割する利点もあります。

-

最後に1つです。ウィンドウ内でこのようなことをしても問題ありませんが、シートを介してこの操作を行うと、アカウントウィンドウの追加が他のウィンドウの背後に隠れる可能性がなくなります。

+0

xcodeで何もわかりません。 :)ので、.xibファイルはNIBです。私は別のNIBで互いに関連している私のインターフェイス要素をすべて整理しなければなりません - ウィンドウとメニュー、コントローラと他のオブジェクト - 今のように1の代わりに - ロードされているものをより良く制御することができます。いつNIBが読み込まれたときにNIBのすべてのUI要素が作成されます...そして、私はawakeFromNibを使ってモデルをインスタンス化し、それをウィンドウの.datasourceにバインドできます。それは正しいと思いますか? –

+0

- windowWillClose通知...これは新しいアカウントコントローラを追加する必要がありますか?またはアカウントのコントローラですか?私はアカウントのコントローラで、それは私がaddNewAccountcontroller変数を使用しているためだと思います。しかし、私はどのように私はここにAddNewAccountウィンドウからwindowWillClose通知を得ることができません表示されません。 –

+0

興味深い注釈...私はあなたがivarを使うことについて、あなたが何を意味しているのかを見ています。(インスタンスvar、またはruby talkの@var)。コントローラをインスタンス化するメソッド内で宣言された標準変数を使用すると、ウィンドウはフォーカスがある限り存続します。ウィンドウがフォーカスを失った後、スコープから外れてガベージコレクションはスコープ内の参照がなくなり、ウィンドウが閉じられるため、ガベージコレクションを再利用することができます。 :P –

関連する問題