LoginSignup
7
7

More than 3 years have passed since last update.

タップした場所にフォーカスを合わせる

Last updated at Posted at 2020-10-19

iPhoneのプリインストールのカメラアプリと同じように、タップした場所にフォーカスします。
Oct-20-2020 01-03-47.gif

手順

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)です。
スクリーンショット 2020-10-19 23.51.20.png
タップした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を使ったアプリを作っています。
機械学習関連の情報を発信しています。

Twitter
Medium

7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7