CocoaBindingでウィンドウの透明度をコントロールするには?

以下のような仕様を実現したい場合、

  • ウィンドウの透明度をコントロールしたい。
  • その透明度をユーザーの好みとして環境設定ファイルに保存しておきたい。

今まで試してきたCocoaBindingを利用すれば簡単!と早速、作業を始めてみたが、すぐに手が止まった...。

ウィンドウのBindingsインスペクタを開いても、透明度を設定する項目は存在しないのだ。でも、NSWindowの透明度をコントロールするメソッドは知っている。以下のようにすれば透明度0.5のウィンドウになって、背景がかなり透けて見える。

[window setAlphaValue:0.5];

Interface Builderに頼らずに、XcodeからコーディングでBindingする方法

ADC Home > Documentaion > 日本語翻訳 > Cocoa バインディングの仕組み > バインディングの詳細によると、bind:toObject:withKeyPath:options:メソッドを利用するとコードからBindingが可能になるようだ。対応関係は以下のようになっている。

図 6:ジョイスティックの角度のバインディング(Interface Builder)

[joystick bind:@"angle"                 /* ▼angle */
      toObject:GraphicController        /* Bind to: */
   withKeyPath:@"selection.shadowAngle" /* Controller Key: . Model Key Path: */
       options:options];                /* Value Transformer:以下 */
http://developer.apple.com/jp/documentation/Cocoa/Conceptual/CocoaBindings/Concepts/HowDoBindingsWork.html#//apple_ref/doc/uid/20002373/194182

ウィンドウの透明度をコントロールしてみる

対応関係が理解できたので、ウィンドウの透明度にBindingする場合を想像して当てはめてみた。

  • bind:には、NSWindowにはalphaVlue、setAlphaValue:というメソドがあるので、alphaValueとしてみた。
  • toObject:には、お決まりのNSUserDefaultsControllerを利用した。
  • withKeyPath:については、Controller Key:とModel Key Path: を「.」で繋ぐ。
    • valuesは、NSUserDefaultsControllerで選択可能な「values」または「hasUnappliedChanges」を順に試してみた。
    • windowAlphaは、自分で決めた任意の名前。
  • option:は無しなのでnil
- (void)awakeFromNib {
    [window bind:@"alphaValue"
        toObject:[NSUserDefaultsController sharedUserDefaultsController]
     withKeyPath:@"values.windowAlpha"
         options:nil];
}

以上でウィンドウの透明度がコントロールできるようになった!

ウィンドウのBindingはAppControllerを作ってawakeFromNibの中で設定している。コードはこれだけ。あとはすべてInterface Builderによる設定だ。

  • AppControllerのインスタンスを追加してアウトレットの接続(AppControllerのwindow)
  • ウィンドウにスライダーを配置。
  • スライダーのAttributes(最小最大を0〜1、Continuousのチェックあり)
  • スライダーのBindings

上記の例は小さなサンプルだけど、Cocoa環境って、Railsよりも遥かに少ないコードしか書かないプログラミング環境になりそう。(デスクトップアプリケーションとwebアプリケーションという開発目標の違いはあるが...。)