twostraws / CodeScanner

A SwiftUI view that is able to scan barcodes, QR codes, and more, and send back what was found.
MIT License
986 stars 272 forks source link

CodeScannerView freezes after returning from child page #120

Open monishkumar7 opened 7 months ago

monishkumar7 commented 7 months ago

Description: I have encountered an issue with the CodeScannerView where it freezes after returning from a child page.

Steps to Reproduce

  1. Navigate to the page containing the CodeScannerView.
  2. Navigate to a child page.
  3. Return to the page containing the CodeScannerView.
  4. Observe that the CodeScannerView becomes unresponsive and frozen.

Expected Behavior

After returning from the child page, the CodeScannerView should continue to function as expected.

Actual Behavior

The CodeScannerView freezes. I don't see the green light on the Dynamic Island too. I think the camera connection is cut off.

epoberezkin commented 7 months ago

That is indeed the case, and the only workaround I found was to force swiftUI to recreate the view this way:

// The hack below prevents camera freezing when exiting child view.
// Using showQRCodeScanner inside qrCodeScannerView or passing it as parameter still results in freezing.
if showQRCodeScanner {
    qrCodeScannerView()
} else {
    qrCodeScannerView(showScanner: false)
}

private func qrCodeScannerView(showScanner: Bool = true) -> some View {
    ZStack {
        if showScanner {
            CodeScannerView(codeTypes: [.qr], completion: processQRCode)
        }
    }
}
monishkumar7 commented 7 months ago

That is indeed the case, and the only workaround I found was to force swiftUI to recreate the view this way:

// The hack below prevents camera freezing when exiting child view.
// Using showQRCodeScanner inside qrCodeScannerView or passing it as parameter still results in freezing.
if showQRCodeScanner {
    qrCodeScannerView()
} else {
    qrCodeScannerView(showScanner: false)
}

private func qrCodeScannerView(showScanner: Bool = true) -> some View {
    ZStack {
        if showScanner {
            CodeScannerView(codeTypes: [.qr], completion: processQRCode)
        }
    }
}

Thank you.

I used the QRCodeScannerView and then used Sheet to keep the background QRCodeScannerView active. That worked.