<週刊 自分のごちうサーチを作る> #4 Xcode の世界と C# の世界をつなぐ
前回記事はこちら。
今回のお品書き。
- ビューのカスタムクラスをつくる
- コントローラにプロパティを生やす
- ユーティリティメソッドを作る
この記事からいよいよ C#+Cocoa の世界に入っていきます。
NSImageView を継承したビューを作る
画像をドラッグ&ドロップされたときの処理を書くために,継承ビューを作っていきます。NSImageView にはイベントが定義されていないので,継承ビュー内にて自分で定義していく必要があります。
Cocoa の世界では伝統的にDelegate (非delegate in C#)でアクションに対する応答を行っています。たとえばNSTableView という表形式のビューを提供するコントロールでは,NSTableViewDelegate を使って項目のドラッグ&ドロップや項目の追加削除再表示などの処理を注入します。NSImageView には外部から注入できるDelegate が定義されていないため,継承していくことになります。
Xcode を開いている場合はいったんXcode を終了します。Xamarin Studio でMyGochiusearch
プロジェクトに Views
フォルダを作ります。
作ったViews
フォルダを右クリックしてして,New File...
を選択します。
General
から Empty Class
を選択し,適当に名前を付けて作成します。ここではAcceptDropImageView
としました。
ここでは細かい実装は行わず,ビューのカスタムクラスとしてXcodeで選択できるようにします。このように実装します。
8行目のFoundation.Register
属性で,Cocoa に公開するクラス名を定義しています。自由に指定できますが,ここではnameof
を使ってC#側クラス名をそのまま反映しています。
コンストラクタはそれぞれXIBからの構築時(IntPtr),実行中のUI構築時(CGRect)に呼ばれます。ここではXIBを結びつけていませんが,Xcodeからカスタムクラスとして指定するために必要です。
ここまでできたらXcodeに戻りましょう。MainWindow.xib を開いて作業しやすいようにXcodeのメインウィンドウ側で開きなおします。MainWindow
内のImageWell
を選択します。ImageCell
までポップアップしますが,こちらではありません。
右のインスペクタをIdentity Inspector
に切り替え(左から3つめ),カスタムクラスに先ほど作ったクラスを指定します。
これでカスタムクラスを指定することができました。
C#側からコントロールにアクセスできるようにする
AssistantEditor
を開きます。Xcode の右上に並んでいるいくつかのボタンのうち,○が二つ重なったようなアイコンです。
MainWindowController.m
が開かれると思いますが,今回は使いません。MainWindowController.h
に切り替えます。
コントローラの定義をひとつずつここに追加していきます。まずは「自動的にニコニコ動画を開く」チェックボックスを選択し,Ctrl+ドラッグでAssistant Editor に引っ張って,Insert Outlet or Action
となったところで離します。
ポップアップで名前を付けて,Connect
をクリックします。
これで接続できました。同様の手順で,検索レベルのポップアップボタン,カスタムクラスを指定したイメージウェルを接続します。
テキストビューは注意して接続する必要があります。このコントロールは以下のような構成になっているからです。
Bordered Scroll View
内にTextView
を内包したClipView
がある,という状態です。これでスクロールした部分だけをクリップして表示することでスクロール可能なテキストビューを実現しています。必要なのはTextView
への接続です。正しいコントロールを接続していれば,ポップアップはこのように出現します。
ついでなので,テキストを編集できないようにしておきます。インスペクタでEditable
をオフにします。
ここまでできたら,Xcode を終了します。
AppDelegate.cs
まずはウィンドウを閉じたとき,アプリケーションが終了するようにしましょう。AppDelegate.cs
を開いて,適当な場所に override appterm
と入力します。
ApplicationShouldTerminateAfterLastWindowClosed
メソッドで true
を返せば,アプリケーションはウィンドウがひとつもなくなった時点で終了します。ということで return true;
などとしておきます。もちろんこう書くことも。
public override bool ApplicationShouldTerminateAfterLastWindowClosed(NSApplication sender) => true;
MainWindowController.cs
MainWindowController.cs
に override WindowDidLoad
メソッドを作成します。これはウィンドウのロード後,コントロールの初期化を始める直前に呼ばれます。このへんに作成するとわかりやすいです。
ユーティリティメソッドを作る
ここでは今後使うであろう3つのユーティリティメソッドを作っておきます。
- ウィンドウにメッセージボックスを表示する
- テキストビューになにか出力する
- テキストビューの内容をクリアする
MainWindowController
クラスのどこかに,下記のように作成します。
ResultView
は先ほど接続したテキストビューの名前に適宜置き換えてください。これらが何をするものなのかはまた別途解説します…が,使ってみればなんとなくわかるはずです。さっそくメッセージボックスを表示しましょう。
メッセージを表示してみる
先ほど作成したWindowDidLoad
内で,次のように記述します。このメソッド内で何かする場合は,必ずbase.WindowDidLoad()
の後に書きます。
デバッグ実行すると,メッセージが表示され,ウィンドウを閉じるとアプリケーションが終了します。
上手にできました。
次回予告
Stay tuned...