Timer サンプルを読む
なかなかアクティベートされなく、手持ち無沙汰なのでとりあえずサンプルを読んでみる(https://github.com/HipByte/RubyMotionSamples)。今日読んだのは Timer というストップウォッチアプリ。実際に動かしていろいろ試しているわけじゃないので、自信がない。
Timer/app/app_delegate.rb
application:didFinishLaunchingWithOptions 起動完了時の動作
UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
は
[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
に対応する。
アプリケーションのウィンドウはUIWindowのインスタンスで表現できる。Objective-Cでは[[Class alloc] init]でインスタンスを生成する([Class new]でもOK)。allocでメモリ領域を確保し、initで初期化だが、initは引数を取らない。引数を渡せるイニシャライザが欲しかったら、引数付きのイニシャライザを作る必要がある(指定イニシャライザ)。
initWithFrameでは画面サイズを渡す必要があり、UIScreen.mainScreen.boundsで取得できる。ここで生成したウィンドウにボタン等のビューを追加していく形で画面に表示していく。
@window.rootViewController = TimerController.alloc.init
TimerControllerはUIViewControllerを継承している。UIViewControllerはビューの管理を行う。Viewガイドによれば、ビューは階層構造を持っており、ビューコントローラがビューの表示を行う。ウィンドウはルートビューオブジェクトを1つ持っているので、これを制御する rootViewControlleを設定してあげる必要がある。それにしてもいちいち.alloc.initと書くのは野暮ったい。
@window.makeKeyAndVisible
メインとなるウィンドウを作成して描画する。
ビューコントローラの管理サイクル
Viewガイドによると、ビューの管理ではロードサイクルとアンロードサイクルという2つのサイクルが独立して発生する。コントローラが管理するビューオブジェクトが必要になった時、オブジェクトがメモリ内に存在しない場合にロードサイクルが発生する。
ロードサイクルでは、ビューがメモリ内に存在しない場合、loadViewメソッドを呼び出し、ビューをロードする。ロード時に実行する処理として、viewDidLoadメソッドが読み出される。
メモリ不足によりビューを解放する必要が出てくるとアンロードサイクルが発生する。ロードサイクルと同様に、ビューの開放と開放した後の処理が呼び出される。
Timer/app/timer_controller.rb
viewDidLoad でロード時に実行する処理を記述
UILabelは文字を表示させる時に私用する。UILabelはUIViewを継承しているので @state.frameで位置と大きさを指定できる。このストップウォッチ以外のUILabelの例を見るとCGRectでサイズをしているけど、ここでは配列で指定されている。このメソッドでのviewはビューコントローラが担当しているビュー、即ちウィンドウ。
view.addSubviewでラベルを追加。
setTitleでボタンの文字をセットする。forStateにはUIControlStateを設定する。addTargetでイベントリスナをセットする。1個目の引数がアクションメッセージを送る対象、:actionはイベントが発生した時の処理、:forControlEventsは補足するイベント。
actionTapped
NSObjectはルートクラス。NeXTSTEPの略らしい。@timerが存在していたらタイマーを止めて、自身をnilにする。scheduledTimerWithTimeIntervalの1番目の引数が繰り返しの時間(秒)。
@action.selectedのデフォルトはfalse
timerFired
0.1秒ごとに呼び出される。
String#%でフォーマットされた文字列が返ってくるんですね。知らなかった。