« UITableViewについて | トップページ | QuartzDemoを読む 1 »

2010年7月 6日 (火)

iphone 開発 サンプル「Simple Undo」を読む。

iPhone OS Reference Libraryに、Simple Undoというサンプルプロジェクトがある。
今回はこれを読みます。

サンプルCoreDataBooksと似てるけど、
あっちはCoreDataのはなしとUndoManagerのはなしが入り交じってて、
正直理解できなかった。私が馬鹿なだけ?

○Undo/Redoの実施について
情報を編集しsaveをタップしたあと、
完了する前にiphoneをシェイクするとundo/redoが起動するようです。

○ファイル構成

SimpleUndoAppDelegate.{h,m}
ブックと最初のビューコントローラを設定する。

RootViewController.{h,m}
ブックについての情報を表示するテーブルビューを管理する。

EditingViewController.{h,m}
編集用のビュー

Book.{h,m}
本をあらわす単純なオブジェクト

このサンプルはCoreDataを使ってないみたい。よかったよかった。

まず、Bookを見る。
下記3つの情報の入れ物。単純。
NSString *title;
NSString *author;
NSDate *copyright;


次に、RootViewController

宣言部分
@interface RootViewController : UITableViewController
となってる。PropertyEditingとは何か?

EditingViewController.hで定義している。
@protocol PropertyEditing
- (void)setValue:(id)newValue forEditedProperty:(NSString *)field;
@end

今までのパターン的には、RootViewControllerを表すdelegateをEditingViewControllerが持ってて、
EditingViewControllerの中で、[delegate setValue]とすることが予想される。

EditingViewController.hのこの部分がそうなんだろう。
id sourceController;

つまり、Rootの方のBookが入力完了後の本物で、
Editingの持ち物はUndoされ得る編集中の途中データのはずです。

ここから、実装について見ていく。

○RootViewController.m
テーブルビューについての話は、飛ばします。

メソッド:setEditing:animated:について
これは、UIViewControllerのメソッドで、テーブルビューを編集中にするかどうかを決める。
これを呼び出す部分は?

明示的な呼び出しはない。
 - (void)viewDidLoad {
self.navigationItem.rightBarButtonItem = self.editButtonItem;
の部分でナビゲーションバーの右側に編集ボタンをつける、という指示をすると、
上記メソッドと結びつく模様。

とりあえずsetEditing:animated:が呼び出されたとき、
これから編集を行うのであれば、undoManagerを生成し、完了したのであれば廃棄している。

NSNotificationCenterは、Undo/Redoの実施が行われた通知を受ける監視者?


メソッド:setValue:forEditedProperty:について

実装の上にコメントがある。翻訳。
##############################################################
このメソッドはブックの値を更新する。
そしてundo/redoの操作も同時に登録する。
実施にはinvocationを使う。なぜならこのメソッドには2つの引数が要るから。
このメソッドは、編集ビューでsaveがタップされたときに実施される。
##############################################################

invocationというところは、undo/redoの実装方法に、simple/invocationの選択肢があり、
1つの値を扱うときはsimple、2つ以上のときはinvocationを使うようです。

まず、undoManagerに「現在の」値を保存
[[undoManager prepareWithInvocationTarget:self] setValue:currentValueforEditedProperty forEditedProperty:field];

つぎに、「編集中の」値を保存(この時点で、bookの値は一時的に編集途中のデータになっている)
[book setValue:newValue forKey:field];

これはよくわからんが、今がundo実施中でないとき(=通常の値セットのとき)undo実施時のキャプション表示に備えて、
フィールドのなまえを登録しているのかも
if (![undoManager isUndoing]) {
[undoManager setActionName:NSLocalizedString(field, @"string provided dynamically")];
}

○SimpleUndoAppDelegate.m

下記の実装によって、shakeでundo/redoが行われる模様。セットしなくてもデフォルでもYESとのこと。
// Tell the application to support shake-to-edit.
application.applicationSupportsShakeToEdit = YES;


○EditingViewController
とくに見るところがなかった。
デリゲートのメソッドを実施しているこの辺くらい。
- (IBAction)save {
if (editingDate) {
[sourceController setValue:datePicker.date forEditedProperty:editedPropertyKey];
}
else {
[sourceController setValue:textField.text forEditedProperty:editedPropertyKey];
}

読んだ限り、シェイクしたときの画面のレイアウトや、undo/redoの実施は自動で行われている模様。
そのソースがない分、直感的には理解しづらいが、
わかってしまえばソースをかかなくてよいので簡単。

おわり。

|

« UITableViewについて | トップページ | QuartzDemoを読む 1 »

iphone開発」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.f.cocolog-nifty.com/t/trackback/1049865/35658843

この記事へのトラックバック一覧です: iphone 開発 サンプル「Simple Undo」を読む。:

« UITableViewについて | トップページ | QuartzDemoを読む 1 »