🎚️

【iOS 18】カメラコントロールで撮影機能を操作する

2024/10/29に公開

iPhone 16シリーズにカメラコントロールが搭載され、撮影で使用する機能に素早くアクセスすることができるようになりました。カメラコントロールを使用することで、端末を持ち替えずに撮影用のパラメータを調整したり、設定項目の選択を行うことができます。

本記事ではiPhone 16シリーズに搭載されているカメラコントロールを操作するための実装方法について解説します。

本記事を最後までお読みいただくことで、カメラコントロールでズーム倍率調整や露出調整、独自のパラメータ調整やピッカーを使用した項目選択を行うことができるようになります。

カメラコントロールとは

カメラコントロールとはiPhone 16シリーズに搭載されている、iPhoneの右側面、電源ボタンの下側に搭載されているボタンです。

カメラコントロールを軽く押すと、カメラコントロールのオーバーレイという領域が表示され、オーバーレイにスライダーやピッカーを表示することができます。

カメラコントロールに対して指を上下にスライドさせることで、カメラのズーム倍率調整や項目選択を行うことができます。カメラコントロールはiOSにプリインストールされているカメラアプリで使用することができますが、サードパーティ製のアプリでも使用することができます。

実装

AVCaptureEventInteraction オブジェクトを追加したUIView オブジェクトを用意します。
そして、AVCaptureControl を継承したクラスのオブジェクトをAVCaptureSession オブジェクトに追加し、AVCaptureSessionControlsDelegate プロトコルに準拠することで、カメラコントロールを使用した各種操作を行うことができます。
はじめに、UIView オブジェクトにAVCaptureEventInteraction オブジェクトを追加する方法を解説し、AVCaptureControl を継承したクラス、キャプチャセッションへの追加方法、デリゲートメソッドの順に解説します。

AVCaptureEventInteractionオブジェクトの追加

UIView オブジェクトのaddInteraction(_:) メソッドで、UIView オブジェクトにAVCaptureEventInteraction オブジェクトを追加することができます。

以下のソースコードは、AVCaptureEventInteraction オブジェクトを追加したカメラ映像プレビューを表示するためのViewです。

AVCaptureControl を継承したクラス

ズーム倍率調整

AVCaptureSystemZoomSlider はカメラコントロールでズーム倍率調整を行うためのクラスです。カメラコントロールのオーバーレイ上に、ズーム倍率調整用のスライダーを表示することができます。AVCaptureSystemZoomSlider オブジェクトはinit(device:) イニシャライザで取得することができます。device 引数には現在使用しているAVCaptureDevice オブジェクトを指定します。

露出調整

AVCaptureSystemExposureBiasSlider はカメラコントロールで露出調整を行うためのクラスです。カメラコントロールのオーバーレイ上に、露出調整用のスライダーを表示することができます。AVCaptureSystemExposureBiasSlider オブジェクトはinit(device:) イニシャライザで取得することができます。device 引数には現在使用しているAVCaptureDevice オブジェクトを指定します。

カスタムパラメータ調整

AVCaptureSlider はカメラコントロールで特定のパラメータを調整調整を行うためのクラスです。カメラコントロールのオーバーレイ上に、アプリ開発者が指定した特定のパラメータ調整用のスライダーを表示することができます。
AVCaptureSlider オブジェクトはinit(_:symbolName:in:) イニシャライザで取得することができます。第一引数にはコントロール選択時に表示する名称を文字列で指定し、symbolName 引数にはSFシンボル名を文字列で指定します。これらはピッカーでコントロール対象を選択する時に表示されます。in 引数にはスライダーの選択範囲を指定します。

スライダーの値を変更した時に実行する処理は、AVCaptureSlider オブジェクトのsetActionQueue(_:action:) メソッドで指定します。第一引数には処理を行うディスパッチキューを指定し、action 引数にはスライダーの値が変化した時に実行する処理をクロージャで指定します。

ピッカー

AVCaptureIndexPicker はカメラコントロールで特定の項目選択を行うためのクラスです。カメラコントロールのオーバーレイ上に、アプリ開発者が指定した項目を選択するためのピッカーを表示することができます。
AVCaptureIndexPicker オブジェクトはinit(_:symbolName:localizedIndexTitles:) イニシャライザで取得することができます。第一引数にはコントロール選択時に表示する名称を文字列で指定し、symbolName 引数にはSFシンボル名を文字列で指定します。これらはピッカーでコントロール対象を選択する時に表示されます。localizedIndexTitles 引数にはピッカーで表示する項目名を文字列の配列で指定します。

ピッカーの項目を変更した時に実行する処理は、AVCaptureIndexPicker オブジェクトのsetActionQueue(_:action:) メソッドで指定します。第一引数には処理を行うディスパッチキューを指定し、action 引数にはピッカーの選択項目が変化した時に実行する処理をクロージャで指定します。

キャプチャセッションの設定

AVCaptureSession オブジェクトのaddControl(_:) メソッドで、AVCaptureControl を継承したオブジェクトをAVCaptureSession オブジェクトに追加することができます。
AVCaptureSession オブジェクトのsupportsControls プロパティで、カメラコントロールに対応しているデバイスかどうかを確認し、canAddControl(_:) メソッドで引数に指定したAVCaptureControl を継承したオブジェクトを、AVCaptureSession オブジェクトに追加することができるかどうかを確認します。

AVCaptureSession オブジェクトのremoveControl(_:) メソッドで、引数に指定したAVCaptureControl オブジェクトをAVCaptureSession オブジェクトから取り除くことができます。

デリゲートメソッド

カメラコントロールを使用するためにはAVCaptureSessionControlsDelegate プロトコルに準拠する必要があります。
・AVCaptureSessionControlsDelegate
https://developer.apple.com/documentation/avfoundation/avcapturesessioncontrolsdelegate

委譲先の指定

AVCaptureSession オブジェクトのsetControlsDelegate(_:queue:) メソッドで、デリゲートメソッドの委譲先を指定します。

カメラコントロールを使用するためにはAVCaptureSessionControlsDelegate プロトコルに準拠する必要があり、準拠先のクラス内で以下のメソッドを定義する必要があります。

  • sessionControlsDidBecomeActive(_:)
  • sessionControlsWillEnterFullscreenAppearance(_:)
  • sessionControlsWillExitFullscreenAppearance(_:)
  • sessionControlsDidBecomeInactive(_:)

sessionControlsDidBecomeActive(_:)

カメラコントロールがアクティブ状態になったタイミングでコールされます。

sessionControlsWillEnterFullscreenAppearance(_:)

カメラコントロールのオーバーレイが、フルスクリーン表示状態になったタイミングでコールされます。

sessionControlsWillExitFullscreenAppearance(_:)

カメラコントロールのオーバーレイが、非表示になる直前にコールされます。

sessionControlsDidBecomeInactive(_:)

カメラコントロールが非アクティブ状態になったタイミングでコールされます。

サンプルソース

参考資料

・Enhancing your app experience with the Camera Control
https://developer.apple.com/documentation/avfoundation/capture_setup/enhancing_your_app_experience_with_the_camera_control

Discussion