11月22日にiPad向けのiOS 4.2がリリースされ、マルチタスキングが導入され、ホームボタンでアプリを終了してもバックグラウンドで動作するようになりました(参照:「iOS 4.2」ついにリリースーー登場8カ月目のiPadを一新するアップデート)。そのため、アプリ終了時の状態を保持する実装の必要性はほぼなくなりましたが、ここではiOS 4.1以前を使っているiPadでも一応対応できるように、書いた絵を意図的に端末に保存する方法について説明します。
canvasを保持するDetailViewControllerに、以下の2つのメソッドを追加します。
@interface DetailViewController : UIViewController <UIPopoverControllerDelegate,UISplitViewControllerDelegate> { ……【省略】…… } ……【省略】…… // 以下を追加 - (void)createBackup; - (void)restoreImage;
- (void) createBackup { NSData *imageData = UIImagePNGRepresentation(canvas.image); [[NSUserDefaults standardUserDefaults] setObject:imageData forKey:@"canvas"]; } // バックアップを復元 - (void) restoreImage { NSData *imageData = [[NSUserDefaults standardUserDefaults] objectForKey:@"canvas"]; canvas.image = [UIImage imageWithData:imageData]; }
createBackupメソッドでは、まず「UIImagePNGRepresentation」という関数を使用してcanvasが保持する画像データ(自分が描いた絵)をPNG形式で「NSData」インスタンスへと変換しています。次にこのNSDataを端末に保存できる「NSUserDefaults」クラスをstandardUserDefaultsメソッドでインスタンス化し、setObjectメソッドで「canvas」という文字列をキーに保存しています。
restoreImageメソッドでは逆に、NSUserDefaultsクラスで保存されたNSDataインスタンスから画像データを復元し、canvas上に展開しています。
次に、このメソッドをアプリの起動時と終了時に呼び出します。Xcodeの[グループとファイル]→[Classes]からSampleOekakiAppDelegateを選択し、以下のように編集します。
// アプリ起動時 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [window addSubview:splitViewController.view]; [window makeKeyAndVisible]; [detailViewController restoreImage]; return YES; } // アプリ終了時 - (void)applicationWillTerminate:(UIApplication *)application { [detailViewController createBackup]; }
どちらのメソッドも「UIApplicationDelegate」プロトコルに定義されており、アプリの起動時と終了時をハンドリングしています。この中でDetailViewControllerに用意したバックアップと復元のメソッドを呼び出すことで、終了時の状態を復元しています。
これで力を入れて作品を描いている最中でも、心置きなくアプリを終了できるようになりました。
アプリ起動時に前回の絵を復元できるようにしましたが、それと同時に最初から絵を描くことができなくなってしまいました。ゴミ箱ボタンを追加し、描いた絵をリセットする機能を付けてみましょう。DetailViewControllerを以下のように編集します。
- (void)viewDidLoad { [super viewDidLoad]; canvas = [[UIImageView alloc] initWithImage:nil]; canvas.backgroundColor = [UIColor whiteColor]; canvas.frame = self.view.frame; [self.view insertSubview:canvas atIndex:0]; // 間隔用ボタンの生成 UIBarButtonItem *spaceBtn = [ [UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:selfaction:nil ]; // ゴミ箱ボタンの生成 UIBarButtonItem *trashBtn = [ [UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:@selector(initCanvas:) ]; // ツールバーにセット NSMutableArray *items = [[toolbar items] mutableCopy]; [items addObject:spaceBtn]; [items addObject:trashBtn]; [toolbar setItems:items animated:NO]; [items release]; [spaceBtn release]; [trashBtn release]; } // キャンバスを初期化 -(void)initCanvas:(id)sender { canvas.image = nil; }
viewDidLoadメソッドでは、ゴミ箱ボタンとゴミ箱ボタンをツールバー右端に配置するための間隔用ボタンを追加しました。間隔を作ったのは、パレット選択時に誤ってゴミ箱ボタンを押さないようにするためです。
次に、ゴミ箱ボタン押下時のアクションにinitCanvasメソッドをセットします。この中では、canvasにセットされている「UIImage」をnilにして画像データをなくすことでリセットされるようにしています。
最後に、描いた絵を端末のフォトアルバムへ保存できるカメラボタンを追加してみましょう。ゴミ箱ボタンと同様にカメラボタンを追加し、saveToPhotoAlbumメソッドに機能を実装します。
- (void)viewDidLoad { [super viewDidLoad]; canvas = [[UIImageView alloc] initWithImage:nil]; canvas.backgroundColor = [UIColor whiteColor]; canvas.frame = self.view.frame; [self.view insertSubview:canvas atIndex:0]; // 間隔用ボタンの生成 UIBarButtonItem *spaceBtn = [ [UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil ]; // ゴミ箱ボタンの生成 UIBarButtonItem *trashBtn = [ [UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:@selector(initCanvas:) ]; // カメラボタンの生成 UIBarButtonItem *cameraBtn = [ [UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:self action:@selector(saveToPhotoAlbum:) ]; // ツールバーにセット NSMutableArray *items = [[toolbar items] mutableCopy]; [items addObject:cameraBtn]; [items addObject:spaceBtn]; [items addObject:trashBtn]; [toolbar setItems:items animated:NO]; [items release]; [cameraBtn release]; [spaceBtn release]; [trashBtn release]; } // キャンバスの画像をフォトアルバムへ保存 -(void)saveToPhotoAlbum:(id)sender { UIImageWriteToSavedPhotosAlbum(canvas.image, nil, nil, nil); }
「UIImageWriteToSavedPhotosAlbum」関数を使用してアルバムに保存しています。引数の1番左が保存対象の画像の指定であり、そのほかはコールバック用(保存後の処理)の引数となっており、完了通知ダイアログを出したりする際に利用します。このサンプルでは画像を保存しているのみのため、すべて「nil」としています。
それでは、絵を描いてカメラボタンを押してみましょう。
端末のフォトアルバムに無事保存ができたら成功です。
今回は、iPad用アプリとしてペイント系アプリ開発の基本部分について解説しました。ここで紹介したCore Graphicsフレームワークの使用方法はごく一部であり、さらに多くの機能を付け加えていくことが可能です。ぜひ、さまざまなアイデアを出して面白いペイント系アプリを作ってみましょう。
サンプル完成版のソースコードは、こちらからダウンロードできます。
次回も、iPhone/iPadアプリ開発におけるさまざまな勘所を紹介していきたいと思いますので、どうぞお楽しみに!
竹内 彰吾(たけうち しょうご)
どこにでもいる職業プログラマであり、好きな言語はJavaとObjective-C。現在は、業務システムの開発に従事し、顧客の要望に日々全力で応えている。
一方、ほかの案件や趣味ではiPhone/Androidアプリ開発にも積極的に取り組んでいる
Copyright © ITmedia, Inc. All Rights Reserved.