Swift - 如何将圆形视图添加到相机视图中?

Swift - How to add a circular view into camera view?

我有一个简单的相机视图控制器,我需要在屏幕中央放置一个圆形视图。我尝试了此处建议的解决方案 but they didn't work. I need something like in the following picture, but blur effect is not necessary: Image link 这是我试过的。它显示了圆圈,但外面的一切都是黑色的:

class CircularCameraViewController: UIViewController {

       var captureSession: AVCaptureSession!
       var capturePhotoOutput: AVCapturePhotoOutput!
    
       override func viewDidLoad() {
           super.viewDidLoad()
            setupCamera()
            setupPhotoOutput()
       }
    
    override func viewDidAppear(_ animated: Bool) {
      super.viewDidAppear(animated)
      captureSession.startRunning()
    }
    
    override func viewWillDisappear(_ animated: Bool) {
      captureSession.stopRunning()
    }

    
    private func setupCamera() {

        let maskLayer = CALayer()
        maskLayer.frame = view.bounds
        let circleLayer = CAShapeLayer()
       
        circleLayer.frame = CGRect(x: view.center.x - 100, y:   view.center.y - 100, width: 200, height: 200)
        let circlePath = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 200, height: 200))
        circleLayer.path = circlePath.cgPath
        circleLayer.fillColor = UIColor.black.cgColor
        maskLayer.addSublayer(circleLayer)
        view.layer.mask = maskLayer

      let captureDevice = AVCaptureDevice.default(for: AVMediaType.video)
      var input: AVCaptureDeviceInput
      do {
        input = try AVCaptureDeviceInput(device: captureDevice!)
      } catch {
        fatalError("Error configuring capture device: \(error)");
      }
      captureSession = AVCaptureSession()
      captureSession.addInput(input)
      
      // Setup the preview view.
      let videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
      videoPreviewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
      videoPreviewLayer.frame = view.layer.bounds
      view.layer.addSublayer(videoPreviewLayer)
    }
    
    private func setupPhotoOutput() {
      capturePhotoOutput = AVCapturePhotoOutput()
      capturePhotoOutput.isHighResolutionCaptureEnabled = true
      captureSession.addOutput(capturePhotoOutput!)
    }

}

我最终使用了这个解决方案

A​​VCaptureVideoPreviewLayer 添加到您的视图层后,添加一个 CAShapeLayer(),如下所示:

let camPreviewBounds = view.bounds
    cropRect = CGRect(
        x: camPreviewBounds.minX + (camPreviewBounds.width - 150) * 0.5,
        y: camPreviewBounds.minY + (camPreviewBounds.height - 150) * 0.5,
        width: 150,
        height: 150
    )
    
    let path = UIBezierPath(roundedRect: camPreviewBounds, cornerRadius: 0)
    path.append(UIBezierPath(ovalIn: cropRect))

    let layer = CAShapeLayer()
    layer.path = path.cgPath
    layer.fillRule = CAShapeLayerFillRule.evenOdd;
    layer.fillColor = UIColor.black.cgColor
    layer.opacity = 0.5;

    view.layer.addSublayer(layer)