前回は、ファイル保存された画像を単純に表示しただけです。実際には、この画像を使い「対称処理」実行することになります。今回は、その準備として、ImageViewControllerへの切り替え方法を再考し、各機能のためのボタンを配置するツールバーも表示します。
まず最初に、Interface Builderを使いImageViewControllerにツールバー(UIToolBar)を配置します。iPhone OS 3.0から、インスペクターの「Shows Toolbar」をチェックすることで、ナビゲーションコントローラ(UINavigationController)付属のツールバーを用意できるようになりました。つまり、複数のビューコントローラを切り換えたとしても、このツールバーは継続して使えるわけです。本アプリなら、RootViewControllerとImageViewControllerで共通のツールバーとして利用可能となります。

しかし、このツールバーにはバーボタンアイテム(UIBarButtonItem)は配置できるのですが、通常のボタン(UIButton)を置こうとすると、何故だか現在のメインビューと差し替えられて配置されてしまいます(涙)。

であれば、ボタン等の配置処理をソースコードで記述することになり、作業を簡単にできるメリットはそれほどありません。今回は、ナビゲーションコントローラのツールバーを使うのは止めて、ImageViewControllerの方だけにツールバーを用意し、そこに必要なボタンやセグメントボタン(UISegmentedControl)を配置することにしました。
ナビゲーションバーとツールバーのアピアランスは半透明の黒(Black Translucent)に統一します。同じく、ステータスバーも半透明の黒にするため、Inteface Builderのインスペクタでナビゲーションコントローラーやキーウィンドウの「それらしきプロパティ」をセットしても、起動するとノーマルステータスバーのままです? 仕方がないので、アプリ起動時に以下のソースコードを追加することで、ステータスバーを好みのタイプに切り替えることにしました。
[UIApplication sharedApplication].statusBarStyle=UIStatusBarStyleBlackOpaque; // ステイタスバーを半透明の黒色に
ImageViewControllerのツールバーには、アバウト表示用の「i」ボタン、 対称処理の方向を決める「上下」と「左右」セグメントボタン、そして処理を元に戻す「リセット」ボタンを配置しておきます。 何故だかセグメントボタンのアピアランスだけは、 半透明の黒いツールバーに配置しても自動で黒色に変更されません(ボタンはされる)?

ナビゲーションバーの左上には、編集した対称写真を写真ライブラリへ保存するための「保存」(Save)ボタンも必要です。Interface BuilderでImageViewController.xlibにバーボタンアイテムをひとつ追加し、ImageViewControllerクラスに用意したIBOutletのim_saveへリンクしておきます。同様にセグメントボタンの方も、IBOutletのim_typeにリンクしておきます。
@interface ImageViewController : UIViewController
{
IBOutlet UIImageView *im_view; // イメージビュー
IBOutlet UIBarButtonItem *im_save; // 保存ボタン
IBOutlet UISegmentedControl *im_type; // タイプグメントボタン
}
そして、ImageViewController.mのviewDidLoad:(ビューコントローラのビューが配置された段階で呼ばれる)をオーバライドし、そこに「保存」ボタンの追加とセグメントボタンの色変更の処理を実装します。
- (void)viewDidLoad
{
[super viewDidLoad]; // スーパークラスを呼び出す
self.navigationItem.rightBarButtonItem=im_save; // 保存ボタン追加
im_type.tintColor=[UIColor grayColor]; // セグメントボタンカラー変更
}
前回は、RootViewControllerのtableView:didSelectRowAtIndexPath:デリゲートで、読み込んだUIImageをopenImageViewControllerWithImage:メソッドに渡しましたが、この箇所を新しく作成したpushImageViewControllerWithImage:メソッドに変更します。 pushViewController:animated:メソッドは好みのビューコントローラをプッシュしてくれます。すると、新しいビューコントローラ(今回はImageViewController)がスライド・アニメーションで表示されます。
- (void)pushImageViewControllerWithImage:(UIImage *)image // イメージビュー・プッシュ
{
if( ! ap_imagevctr )
ap_imagevctr=[[ImageViewController alloc]initWithNibName:@"ImageViewController" bundle:nil];
if( ap_imagevctr )
{
[navigationController pushViewController:(UIViewController *)ap_imagevctr animated:YES];
ap_imagevctr.im_view.image=image;
}
}
また、openImageViewControllerWithImage:メソッドをこのまま削除してしまうのは惜しいので、openAboutViewControllerWithImage:と名称変更し、「i」ボタンをタップすることで、アバウト用のAboutViewControllerをカールアップ・アニメーションで表示することにしました。
- (void)openAboutViewController // アバウトビュー表示
{
if( ! ap_aboutvctr )
ap_aboutvctr=[[AboutViewController alloc]initWithNibName:@"AboutViewController" bundle:nil];
if( ap_aboutvctr )
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:window cache:YES];
[window addSubview:ap_aboutvctr.view];
[UIView commitAnimations];
}
}

プッシュされたImageViewControllerの左上には「画像一覧」ボタンが表示され、それをタップすることで、RootViewControllerへ戻ること(ポップ処理)が可能です。前回のテーブルビューの選択では、タップの時点で青い選択表示を消していたのですが、今回は、この処理をRootViewControllerのviewWillAppear:animatedメソッド内に移します。
NSIndexPath *path;
if( path=[self.tableView indexPathForSelectedRow] ) // 選択行を得る
[self.tableView deselectRowAtIndexPath:path animated:NO]; // 選択を消す
つまり、RootViewController戻った時点で始めて行選択を消すようにするわけです。Apple社の各サンプルソースコードを調べてみると、これが一般的な行選択の消去方法のようです。ところが、iPhone OS 2.0までは、消去時に綺麗なディゾルブ・アメーションが実行されていたのですが、2.2からはそのアニメーションが表示されなくなりました。3.0でもこの現象は直っていません。仕様変更か?バグなのか?現状では判断尽きかねます...。
今回は、ImageViewControllerへの切り替え方法を変更し、ボタンやセグメントボタンを配置したツールバーも用意しました。次回は、実際に対称処理を実装する前の最後の準備、テーブルビューに並んだ画像の名称変更、順序変更、削除といった編集処理を解説いたします。