2008年11月22日土曜日

CS193P - ここまでの進捗をアップしてみた

ここまでのCS193Pの進捗をアップしてみました。

http://sites.google.com/site/akisutesama/files/HelloPoly-06.zip?attredirects=0

Xcode3.1用のプロジェクトファイルと、ソース一式が入っています。
Max OS Xで解凍してXcodeで読み込んでコンパイルできると思います。たいした内容ではありませんが一応。

CS193P Cocoa Programming - 6日目、NSUserDefaultsの使い方

  • アプリケーションが終了した後もデータを保持したい(例:現在開いているページなど)
  • NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
  • あとはNSDictionaryとほとんど同じ(格納の仕方も取得の仕方も)
  • BOOLとかintをそのまま格納できるメソッドもあります
  • 格納するタイミングは、値がかわった瞬間かまたはアプリが終了する瞬間
  • 取得するタイミングは、アプリが立ち上がった瞬間かまたはawakeFromNibメソッド
今日はNSUserDefaultsとやらの使い方を学習。
NSUserDefaultsとはアプリケーションが終了した後もデータを保持することができる仕組みのようです。
本格的にデータを保存したいならSQLiteやファイルを使うんでしょうが、ちょっとしたデータ(例えば現在開いているページ)を保持したいときなどにSQLを書くのは煩雑です。そういうときに便利に使える仕組みらしいです。

○値を格納する
タイミングは二つ。値がかわった瞬間か・・・
//ボタン押し下げ時に値を減らす
- (IBAction)decrease {
int currentNum = polygonShape.numberOfSides;
currentNum--;
polygonShape.numberOfSides = currentNum;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setInteger:currentNum forKey:@"numberOfSides"];
[self updateInterface];
}
またはアプリケーションが終了するタイミングか。
//@implementation HelloPolyAppDelegate(アプリケーションのデリゲートの中で)
- (void)applicationWillTerminate:(UIApplication *)application {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setInteger:controller.model.intValue forKey:@"numberOfSides"];
}
パフォーマンスに応じてどちらか好きな方を選んでくださいとのことです。

○値を取得する
こちらもタイミングは二つ。アプリケーションが立ち上がったタイミングか・・・
//@implementation HelloPolyAppDelegate(アプリケーションのデリゲートの中で)
- (void)applicationDidFinishLaunching:(UIApplication *)application {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
int storedNumberOfSides = [defaults integerForKey:@"numberOfSides"];
controller.model.intValue = storedNumberOfSides;
[window makeKeyAndVisible];
}

または対象のクラスのawakeFromNibメソッドの中か。
//ここではコントローラクラスの中で・・・
- (void)awakeFromNib {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
int storedNumberOfSides = [defaults integerForKey:@"numberOfSides"];
self.model.intValue = storedNumberOfSides;
[self updateInterface];
}

この二つの違いは正直わかってません。複数のNibファイルを利用するときはawakeFromNibでないと駄目らしいですが・・・

CS193P Cocoa Programming - 5日目、いよいよView自作

  • Interface Builderを使ったらとにかくWrite Class Files...を押すのを忘れないように
  • 描画はJavaのSwingなどとほぼ同じ
  • drawRectメソッドをオーバーライドして描画する
ViewとかAnimationとか、いよいよ実践が近くなってきたようです。
だんだんと難易度も上がってきました。



まずは自作Viewを作成。
Interface BuilderからUIViewを引っ張ってきて画面上に配置。
クラス名を適当に(ここではPolygonView)に変更。
ControllerクラスやらModelクラスなど、必要に応じてOutletを追加します。
最後に(一番忘れやすいんだけれども)メニューからFile > Write Class Files... この書き出しを行わないとXcode上に実際のソースが出てきません。

書き出しを行ったらXcodeを開いて、以下の2つの仕事を行います。
・先ほど追加したPolygonViewのスーパークラスを定義する
・ControllerにIBOutlet PolygonView *polygonViewを追加する

新しいオブジェクトはWrite Class Filesで一発だと思うけれども、既存のクラス(例えば前回実装したController)なんかは、書き出ししちゃうと上書きしてしまいそう。怖いので今回はXcodeから書くことにしました。でもこれ非常に非効率的。hファイルだけ上書きしてほしいんですけど・・・



勇気を振り絞って上書きWrite Class Files...にチャレンジしたら、なんだかこんなFileMergeとかいうアプリが立ち上がって、きれいにマージすることができましたとさ。よかったよかった。


では早速Viewに描画処理を追加します。
描画を行うのはUIViewの-(void)drawRect:(CGRect)rectメソッドですので、こいつをオーバーライド。
あとは再描画したいタイミングでUIViewのsetNeedsDisplayをコールすれば適切なタイミングでシステムが再描画してくれるというしくみ。Swingに似てますね。



実際に描画してみました。簡単簡単!!



描画のやり方さえわかってしまえばこっちのものです。
ポリゴンの点の位置を計算するメソッドは例題の中で用意されていたので、それを丸コピーして点の位置に線を引くだけ。線の太さを調節する関数はCGContextSetLineWidthというのが見つかったのでそれを使うだけ。リファレンスが使いやすい!すてき!



カスタムビューの中にUILabelを追加して、ラベルにポリゴンの名称を表示できるようにしてみました。UILabel.textプロパティを書き換えるタイミングはカスタムビューのdrawRectの中で。ほかに良いタイミングが見当たらず。


ひとまずこんなところですかね。次は・・・
  • スライダーで線の太さを変える
  • 線の種類を何らかのスイッチで変える
  • ビューの上でフリックしたらポリゴンがくるくる回るようにする(アニメーション処理の勉強が必要)
これらを試してみたいですね。