iPhoneのプリインストールのカメラアプリと同じように、タップした場所にフォーカスします。
手順
1、タップでView内の座標を取る
UITapGestureRecognizerをカメラのプレビューレイヤーを含むViewに加えます。
タップで以下の関数を呼びます。
@objc func tapForcus(_ recognizer:UITapGestureRecognizer) {
let pointInView = recognizer.location(in: recognizer.view)
print(pointInView)
// (562.0, 282.0)
}
2、View内のタップ座標を、AVCapturePreviewLayer内の座標(0〜1)に正規化する
カメラ画像領域の座標は、常にLandScapeLeftの左上が(0,0)右下が(1,1)です。
タップしたView座標をカメラ画像領域の座標に変換するには、AVCapturePreviewLayerの座標変換メソッドが使えます。
let pointInCamera = previewLayer?.captureDevicePointConverted(fromLayerPoint: pointInView)
print(pointInCamera)
// Optional((0.38380281690140844, 0.41796875))
3、取得した座標にフォーカスを合わせる
フォーカスの関心ポイントをタップしたポイントに設定してから、フォーカスモードを設定しなおします。
関心ポイントを設定した後で、都度フォーカスモードを設定します。でないと、フォーカスされません。
// avCaptureDeviceは、当該セッションのAVCaptureDevice
do {
try avCaptureDevice.lockForConfiguration()
avCaptureDevice.focusPointOfInterest = pointInCamera!
avCaptureDevice.focusMode = .autoForcus // .autoForcus(固定) もしくは .continuousAutoFocus(デバイスによる自動監視継続)
avCaptureDevice.unlockForConfiguration()
} catch let error {
print(error)
}
おまけ:フォーカスアニメーション
フォーカスビューの設定
var forcusView = UIView()
var forcusView = UIView()
forcusView.frame = CGRect(x: 0, y: 0, width: view.bounds.width * 0.3, height: view.bounds.width * 0.3)
forcusView.layer.borderWidth = 1
forcusView.layer.borderColor = UIColor.systemYellow.cgColor
forcusView.isHidden = true
タップでアニメーション
// @objc func tapForcus(_ recognizer:UITapGestureRecognizer) {
// let pointInView = recognizer.location(in: recognizer.view)
forcusView.center = pointInView // タップしたポイントへ移動する
forcusView.isHidden = false // 現れる
UIViewPropertyAnimator.runningPropertyAnimator(withDuration: 0.5, delay: 0, options: []) {
self.forcusView.frame = CGRect(x: point.x - (self.view.bounds.width * 0.075), y: point.y - (self.view.bounds.width * 0.075), width: (self.view.bounds.width * 0.15), height: (self.view.bounds.width * 0.15)) // タップしたポイントに向けて縮む
} completion: { (UIViewAnimatingPosition) in
Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { (Timer) in
self.forcusView.isHidden = true // 少し待ってから消える
self.forcusView.frame.size = CGSize(width: self.view.bounds.width * 0.3, height: self.view.bounds.width * 0.3) // 少し大きめのサイズに戻しておく
}
🐣
お仕事のご相談こちらまで
rockyshikoku@gmail.com
Core MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。