今回はアプリからカメラを呼び出した際に、UIViewを重ねてみる。
※なお、今回はソースを簡単にするためdelegateは省いてある
ちなみに、単に画像を重ねるだけなら簡単だ。
まずはStoryboardで以下のようにボタンを配置しよう。
それから、このボタンのイベントとして
※なお、今回はソースを簡単にするためdelegateは省いてある
ちなみに、単に画像を重ねるだけなら簡単だ。
まずはStoryboardで以下のようにボタンを配置しよう。
それから、このボタンのイベントとして
- (IBAction)launchCamera:(id)sender;
をViewController.hに設定しておく。
ボタンを押したらカメラが起動するように以下のようにソースを追加する。
実行するとこのようになる。
左上に画像が表示されているのがわかるだろうか。
ここまでは前座だ。
いよいよ本題に入ろう。
と、その前に一つ大事なことを付け加えておく。
UIImagePickerControllerのsourceTypeの設定よりも先に
picker.cameraOverlayView = imageView;
を記述すると実行時にアプリが落ちるので注意しよう。
ダメな例
独自のUIViewをcameraOverlayViewに設定する
それでは独自のViewを追加してみよう。
レイアウトが簡単に行えるようにインターフェースビルダーを使用することにする。
ファイルの新規作成でUserInterface → Viewを選択する
OverlayView.xibという名前で保存しよう。
保存し終えたら、以下のようにボタンと画像を配置する。
それと、このままだとカメラのViewをすっぽり覆ってしまい、カメラプレビューが見えなくなるので、大元のViewの背景を透明にしておく。
次はそのレイアウト用のクラスを作成しよう。
Cocoa Touch → Objective-C classを選択する。
Class名をOverlayに、親クラスをUIViewにする。
保存し終えたら、OverlayView.xibに関連付けよう。
Identity inspectorで以下のように設定する。
これでOverlayViewクラスにTest Buttonのイベントが設定できるようになるので
次はカスタムクラスの実装だ。
OverlayView.mを以下のように実装する。
次はViewControllerにカスタムクラスを組み込んでいく。
ViewController.mでOverlayView.hをimportする。
次はカメラの呼び出し部分だ。
リスト1−1を次のように変更する。
これで実行してみよう。
予定通りの結果を得ることが出来た!
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と入力する。
これで準備は完了だ。
Test Buttonの範囲をタッチした場合はYESを返すようになった。
実行してみよう。
バッチリだ!
撮影ボタンを押した後でも、全てのボタンが反応するようになった。
実行するとこのようになる。
左上に画像が表示されているのがわかるだろうか。
ここまでは前座だ。
いよいよ本題に入ろう。
と、その前に一つ大事なことを付け加えておく。
UIImagePickerControllerのsourceTypeの設定よりも先に
picker.cameraOverlayView = imageView;
を記述すると実行時にアプリが落ちるので注意しよう。
ダメな例
独自のUIViewをcameraOverlayViewに設定する
それでは独自のViewを追加してみよう。
レイアウトが簡単に行えるようにインターフェースビルダーを使用することにする。
ファイルの新規作成でUserInterface → Viewを選択する
OverlayView.xibという名前で保存しよう。
保存し終えたら、以下のようにボタンと画像を配置する。
それと、このままだとカメラのViewをすっぽり覆ってしまい、カメラプレビューが見えなくなるので、大元のViewの背景を透明にしておく。
次はそのレイアウト用のクラスを作成しよう。
Cocoa Touch → Objective-C classを選択する。
Class名をOverlayに、親クラスをUIViewにする。
保存し終えたら、OverlayView.xibに関連付けよう。
Identity inspectorで以下のように設定する。
これでOverlayViewクラスにTest Buttonのイベントが設定できるようになるので
- (IBAction)testButtonTapped:(id)sender;
を設定してTest Buttonと連結しておく。次はカスタムクラスの実装だ。
OverlayView.mを以下のように実装する。
次はViewControllerにカスタムクラスを組み込んでいく。
ViewController.mでOverlayView.hをimportする。
次はカメラの呼び出し部分だ。
リスト1−1を次のように変更する。
これで実行してみよう。
予定通りの結果を得ることが出来た!
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と入力する。
これで準備は完了だ。
Test Buttonの範囲をタッチした場合はYESを返すようになった。
実行してみよう。
バッチリだ!
撮影ボタンを押した後でも、全てのボタンが反応するようになった。
コメント