2017-04-05 9 views
2

UIViewControllerにフルスクリーンを表示しないカスタムカメラビューがあります。その下にはコレクションビューがあり、そこに「X」で撮影した画像の小さなサムネイルが埋め込まれています。保存した画像をファイアベースにアップロードする前に削除することができます。カスタムカメラビューのプレビューレイヤープラスサイズの携帯電話の問題

これはすべて、IPhone 7サイズのスクリーンで美しいです。しかし、プラスのサイズの携帯電話に、カスタムカメラビューのプレビュー層は、カメラが中に配置されていることを全体のUIViewを満たしていません。

override func viewWillAppear(_ animated: Bool) { 
    super.viewWillAppear(animated) 

    let deviceSession = AVCaptureDeviceDiscoverySession(deviceTypes: 
     [.builtInDuoCamera, .builtInTelephotoCamera, .builtInWideAngleCamera], mediaType: AVMediaTypeVideo, position: .unspecified) 

    for device in (deviceSession?.devices)! { 
     if device.position == AVCaptureDevicePosition.back { 
      do { 
       let input = try AVCaptureDeviceInput(device: device) 

       if captureSession.canAddInput(input) { 
        captureSession.addInput(input) 

        if captureSession.canAddOutput(sessionOutput) { 
         captureSession.addOutput(sessionOutput) 

         previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) 
         previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill 
         previewLayer.connection.videoOrientation = .portrait 

         cameraView.layer.addSublayer(previewLayer) 
         cameraView.addSubview(takePhotoButton) 

         previewLayer.position = CGPoint(x: self.view.frame.width/2, y: self.cameraView.frame.height/2) 
         previewLayer.bounds = cameraView.frame 

         captureSession.startRunning() 
        } 
       } 
      } catch let avError { 
       print(avError) 
      } 
     } 
    } 
} 

私はどのCameraViewのサブレイヤとしてプレビュー層を追加するのはここですUIViewは、インターフェイスビルダの下にあるコレクションビューのためのビュー内のスペースを許すための制約を加えてインターフェイスビルダに追加されたものです。

previewLayer.position = CGPoint(x: self.cameraView.frame.width/2, y: self.cameraView.frame.height/2) 
previewLayer.bounds = cameraView.frame 

サブレイヤとして追加プレビュー層には異なっIphone7のiphoneの7プラスよりも振る舞うだろう、なぜ私は理解していません? 特に、Iphone 7 Plusでは、CameraViewが正しく制約されていることを示すプレビューレイヤーの周りにグレーが表示されるため、frame.widthが異なるのはなぜですか?

プレビューレイヤーは、通常のサイズの電話機と同じサイズのままですが、CameraView自体は大きな電話機の画面に正しく準拠しています。ここ

問題のビューは、インターフェイスビルダー

here is the View in question in the interface builder

であり、これはプラスサイズの携帯電話

And this is what seems to happen on a plus size phone

+0

'viewWillAppear()'の代わりにコントローラの 'viewDidLayoutSubviews()'メソッドにサブビューを追加しようとするとどうなりますか? Autolayout関連の問題のように聞こえます。 – nshuman

+0

私はそれを試してみましょう。そのコードブロック全体をviewDidLayoutSubviews()に移動することをお勧めしますか?残念ながら私はプラスサイズの携帯電話を持っていないので、テストフライトテスターが動作するかどうかを知るのを待つ必要があります。 –

+0

'viewDidLayoutSubviews()'に 'previewLayer.position'と' previewLayer.bounds'を設定することをお勧めします。あなたの問題は、 'viewWillAppear()'が実行された時点で、Autolayoutは実際のデバイスサイズに対して 'cameraView.frame'を再計算しませんでしたが、あなたのストーリーボードに設定したサイズを使用する可能性が高いです。 'viewDidLayoutSubviews()'メソッドはこの目的のためだけに存在し、この特定のデバイスに対して再計算された実際のサイズを使用します。 – nshuman

答えて

1

TL上で起こるようです何である; DR:viewDidAppear()メソッドでビューとレイヤの座標とフレームを設定します。 viewWillAppear()メソッドが実行時に


、すべてのView Controllerのサブビューは、あなたのストーリーボードに設定したframe値を持っています。必要なのは、previewLayer.positionpreviewLayer.boundsを正しく設定するために、更新されたcameraView.frameの値を実際のデバイスサイズに再計算して使用することです。この目的のためだけにviewDidLayoutSubviews()メソッドが存在します。実行時には、特定のデバイスアプリケーションが実行されているため、すべてのビューの実際のサイズが再計算されます。

viewDidLayoutSubviews()複数回呼び出すことができますが、ビュー/レイヤーの複数のインスタンスが作成される可能性があります。ビューコントローラのライフサイクルには、自動レイアウトされたサブビューを一度だけ呼び出す方法があります。viewDidAppear()です。

だから、previewLayerの関連コードをviewWillAppear()からviewDidAppear()に移動する必要があります。