今回はアプリからカメラを呼び出した際に、UIViewを重ねてみる。
※なお、今回はソースを簡単にするためdelegateは省いてある
ちなみに、単に画像を重ねるだけなら簡単だ。

まずはStoryboardで以下のようにボタンを配置しよう。
camera_overlay_ss1
それから、このボタンのイベントとして

- (IBAction)launchCamera:(id)sender;
をViewController.hに設定しておく。

ボタンを押したらカメラが起動するように以下のようにソースを追加する。

実行するとこのようになる。
camera_overlay_ss2
左上に画像が表示されているのがわかるだろうか。
ここまでは前座だ。
いよいよ本題に入ろう。

と、その前に一つ大事なことを付け加えておく。
UIImagePickerControllerのsourceTypeの設定よりも先に
picker.cameraOverlayView = imageView;
を記述すると実行時にアプリが落ちるので注意しよう。

ダメな例


独自のUIViewをcameraOverlayViewに設定する
それでは独自のViewを追加してみよう。
レイアウトが簡単に行えるようにインターフェースビルダーを使用することにする。

ファイルの新規作成でUserInterface → Viewを選択する
camera_overlay_ss3
OverlayView.xibという名前で保存しよう。
保存し終えたら、以下のようにボタンと画像を配置する。
camera_overlay_ss6
それと、このままだとカメラのViewをすっぽり覆ってしまい、カメラプレビューが見えなくなるので、大元のViewの背景を透明にしておく。
camera_overlay_ss9

次はそのレイアウト用のクラスを作成しよう。
Cocoa Touch → Objective-C classを選択する。
camera_overlay_ss4
Class名をOverlayに、親クラスをUIViewにする。
camera_overlay_ss5
保存し終えたら、OverlayView.xibに関連付けよう。
Identity inspectorで以下のように設定する。
camera_overlay_ss7
これでOverlayViewクラスにTest Buttonのイベントが設定できるようになるので

- (IBAction)testButtonTapped:(id)sender;

を設定してTest Buttonと連結しておく。

次はカスタムクラスの実装だ。
OverlayView.mを以下のように実装する。

次はViewControllerにカスタムクラスを組み込んでいく。
ViewController.mでOverlayView.hをimportする。

次はカメラの呼び出し部分だ。
リスト1−1を次のように変更する。

これで実行してみよう。
camera_overlay_ss12
予定通りの結果を得ることが出来た!
Test Buttonタップ時のデバッグ出力もちゃんと出来ている。

ただし、ここで一つ重大な罠がある。
真ん中下の撮影ボタンを押すと、その後のRetakeボタンとUse Photoボタンが反応しなくなってしまう。
さてどうしたものかと調べていると、こちらのサイトに解決法が書いてあった。

Camera Overlay Viewを設定するとiOS 7.0以降でアプリが操作不能になる問題への対処方法 - 甘いものが好きです

どうもiOS7以降でのみ起こる問題らしく、おそらくiOSのバグであろう。
解決方法は、cameraOverlayViewに指定するViewでpointInside: withEvent:メソッドをオーバーライドすればいいとのこと。
OverlayView.mに以下のメソッドを追加しよう。

実行してみると、RetakeボタンもUse Photoボタンも効くようになった!
だがちょっと待ってほしい。
今度はTest buttonが反応しなくなっている。

実はpointInside: withEvent:の返り値を全てNOにしてしまったせいだ。
このメソッドは今回作成したOverlayViewに対しての処理を書いているため、OverlayViewもそのSubViewも全て反応しなくなってしまったというわけだ。

ではどうすればいいか。
Test Buttonの範囲をタッチされた場合のみYESを返すようにすれば良い。
以下のように修正しよう。

次にOverlayView.xibを開いてTest Buttonを選択した状態でAttributes Inspectorを開く。
下にスクロールするとTagという項目があるので、ここに10と入力する。
camera_overlay_ss11
これで準備は完了だ。
Test Buttonの範囲をタッチした場合はYESを返すようになった。

実行してみよう。
バッチリだ!
撮影ボタンを押した後でも、全てのボタンが反応するようになった。