xcode 正在创建AVCaptureVideoPreviewLayer对象-不允许从视图更新中发布更改,这将导致未定义的行为

eqqqjvef  于 2022-11-17  发布在  其他
关注(0)|答案(1)|浏览(144)

我尝试使用AVKit打开摄像机,在创建CameraView和AVCaptureVideoPreviewLayer对象时出现以下错误:
Publishing changes from within view updates is not allowed, this will cause undefined behavior.
我知道可以通过添加DispatchQueue.main.async {}来解决这个问题,但我不知道确切地把它放在哪里。
我正在创建CameraView,如下所示:

CameraView(size: geometry.size)
                            .environmentObject(cameraViewModel)
                            .ignoresSafeArea()

在里面,它看起来像:

struct CameraView: UIViewRepresentable {
    @EnvironmentObject var cameraViewModel: CameraViewModel
    
    var size: CGSize
    
    func makeUIView(context: Context) -> UIView {
        let view = UIView()
        
        /* error occurs here */
        cameraViewModel.capturePreview = AVCaptureVideoPreviewLayer(session: cameraViewModel.captureSession)

        cameraViewModel.capturePreview.frame.size = size
        
        cameraViewModel.capturePreview.videoGravity = .resizeAspectFill
        
        view.layer.addSublayer(cameraViewModel.capturePreview)
        
        return view
    }
    
    func updateUIView(_ uiView: UIView, context: Context) {
        
    }
}

最后,CameraViewModel保存capturePreview,即:

@Published var capturePreview: AVCaptureVideoPreviewLayer!
agxfikkp

agxfikkp1#

我通过从cameraViewModel中删除@Published var capturePreview: AVCaptureVideoPreviewLayer!并重新构造CameraView来解决这个问题,如下所示:

struct CameraView: UIViewRepresentable {
    @EnvironmentObject var cameraViewModel: CameraViewModel
    
    var size: CGSize
    
    func makeUIView(context: Context) -> UIView {
        let view = UIView()
        view.layer.addSublayer(setupCapturePreview())
        return view
    }
    
    func updateUIView(_ uiView: UIView, context: Context) {
        
    }
    
    private func setupCapturePreview() -> AVCaptureVideoPreviewLayer {
        let capturePreview = AVCaptureVideoPreviewLayer(session: cameraViewModel.captureSession)
        capturePreview.frame.size = size
        capturePreview.videoGravity = .resizeAspectFill
        return capturePreview
    }
}

相关问题