在SwiftUI类中调用包装的UIViewController的函数时获取零

所以下面是我拍摄的一张简单的ViewController图片

final class TakephotoviewController : UIViewController,AVCapturePhotoCaptureDelegate {
    var captureSession : AVCaptureSession!
    var cameraOutput : AVCapturePhotoOutput!
    var previewLayer : AVCaptureVideoPreviewLayer!
    let device = AVCaptureDevice.default(for: .video)!

    override func viewDidLoad(){
        print("viewDidLoad")
        setupCameraLayouts()
    }

   private func setupCameraLayouts(){
        print("setupCameraLayouts")
        captureSession = AVCaptureSession()
        previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)

        captureSession.sessionPreset = AVCaptureSession.Preset.hd1920x1080
        cameraOutput = AVCapturePhotoOutput()
        previewLayer.frame = CGRect(x: view.frame.origin.x,y: view.frame.origin.y+view.frame.height/13,width: view.frame.width,height: view.frame.height/1.2475)

        do {
            try device.lockForConfiguration()
        } catch {
            return
        }

        device.focusMode = .continuousAutoFocus
        device.unlockForConfiguration()
    }

    private func startCamera(){
        print("startCamera")
        if let input = try? AVCaptureDeviceInput(device: device) {
            if captureSession.canAddInput(input) {
                captureSession.addInput(input)
                if captureSession.canAddOutput(cameraOutput){
                    captureSession.addOutput(cameraOutput)
                    view.layer.addSublayer(previewLayer)
                    captureSession.startRunning()
                } else {
                    print("else in : captureSession.canAddOutput(cameraOutput)")
                }
            } else {
                print("else in : captureSession.canAddInput(input)")
            }
        } else {
            print("else in : input = try? AVCaptureDeviceInput(device: device)")
        }
    }

    func camerapressed(){
        print("camerapressed")
        let settings = AVCapturePhotoSettings()
        let previewPixelType = settings.availablePreviewPhotoPixelFormatTypes.first!
        let previewFormat = [
            kCVPixelBufferPixelFormatTypeKey as String: previewPixelType,kCVPixelBufferWidthKey as String: 160,kCVPixelBufferHeightKey as String: 160
        ]
        settings.previewPhotoFormat = previewFormat
        cameraOutput.capturePhoto(with: settings,delegate: self)
    }

    func photoOutput(_ output: AVCapturePhotoOutput,didFinishProcessingPhoto photo: AVCapturePhoto,error: Error?){
        print("photoOutput")
        captureSession.stopRunning()
        print("Got something")
    }
}

extension TakephotoviewController : UIViewControllerRepresentable {

    public typealias UIViewControllerType = TakephotoviewController

    func makeUIViewController(context: UIViewControllerRepresentableContext<TakephotoviewController>) -> TakephotoviewController {
        print("makeUIViewController")
        return TakephotoviewController()
    }

    func updateUIViewController(_ uiViewController: TakephotoviewController,context: UIViewControllerRepresentableContext<TakephotoviewController>) {
        print("updateUIViewController")
    }
}

如您所见,我使用UIViewControllerRepresentable对其进行了“包装”,因此可以在SwiftUI视图中使用它。除非有更好的方法可以做到这一点,否则我发现这是唯一的方法。

下面是我称之为的SwiftUI类。

struct ContentView: View {
    let TPVC = TakephotoviewController()
    var body: some View {
        VStack {
            TPVC.startCamera()
            Button(action: {
                self.TPVC.camerapressed()
            }) {
                Text("Hello World")
                    .fontWeight(.bold)
                    .font(.title)
                    .padding()
                    .background(Color.purple)
                    .cornerRadius(40)
                    .foregroundColor(.white)
                    .padding(10)
                    .overlay(
                        RoundedRectangle(cornerRadius: 40)
                            .stroke(Color.purple,lineWidth: 5)
                    )
            }
        }
    }
}

所以我(从打印语句中)知道TakePhotoVC正在被调用,并且nil错误变量(以及实际上所有变量)都不为零。 就是说,当错误发生时(也就是当我单击按钮时),各种变量(captureSession,CaptureOutput)均为nil,这会导致明显的错误。在ContentView中,我为类实例创建了一个变量,因此我可以在任何时候引用它,但是似乎如果您再次调用它,它将创建一个全新的类引用/实例

xiaohua558 回答:在SwiftUI类中调用包装的UIViewController的函数时获取零

您的ContentView是一个结构,即。值,它将在每次UI刷新时重新创建,因此您的TPVC也将重新创建。

此外,UIViewControllerRepresentable应该是在ViewBuilder中使用的某些View。因此,这在您的代码中是错误的概念。

教程Interfacing with UIKit应该会为您提供帮助。

本文链接:https://www.f2er.com/3107188.html

大家都在问