修复首次授予相机权限后扫码页黑屏
This commit is contained in:
@ -14,6 +14,7 @@ final class QRCodeScannerViewController: BaseViewController, AVCaptureMetadataOu
|
|||||||
|
|
||||||
private let captureSession = AVCaptureSession()
|
private let captureSession = AVCaptureSession()
|
||||||
private var previewLayer: AVCaptureVideoPreviewLayer?
|
private var previewLayer: AVCaptureVideoPreviewLayer?
|
||||||
|
private var isCameraConfigured = false
|
||||||
private var hasHandledResult = false
|
private var hasHandledResult = false
|
||||||
|
|
||||||
private let maskView = UIView()
|
private let maskView = UIView()
|
||||||
@ -60,17 +61,21 @@ final class QRCodeScannerViewController: BaseViewController, AVCaptureMetadataOu
|
|||||||
checkCameraPermission()
|
checkCameraPermission()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func viewDidAppear(_ animated: Bool) {
|
||||||
|
super.viewDidAppear(animated)
|
||||||
|
updatePreviewLayout()
|
||||||
|
startCaptureSessionIfNeeded()
|
||||||
|
}
|
||||||
|
|
||||||
override func viewDidLayoutSubviews() {
|
override func viewDidLayoutSubviews() {
|
||||||
super.viewDidLayoutSubviews()
|
super.viewDidLayoutSubviews()
|
||||||
previewLayer?.frame = view.bounds
|
updatePreviewLayout()
|
||||||
updateMask()
|
updateMask()
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewWillDisappear(_ animated: Bool) {
|
override func viewWillDisappear(_ animated: Bool) {
|
||||||
super.viewWillDisappear(animated)
|
super.viewWillDisappear(animated)
|
||||||
if captureSession.isRunning {
|
stopCaptureSession()
|
||||||
captureSession.stopRunning()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func checkCameraPermission() {
|
private func checkCameraPermission() {
|
||||||
@ -94,11 +99,21 @@ final class QRCodeScannerViewController: BaseViewController, AVCaptureMetadataOu
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func setupCamera() {
|
private func setupCamera() {
|
||||||
|
if isCameraConfigured {
|
||||||
|
updatePreviewLayout()
|
||||||
|
startCaptureSessionIfNeeded()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
guard let device = AVCaptureDevice.default(for: .video),
|
guard let device = AVCaptureDevice.default(for: .video),
|
||||||
let input = try? AVCaptureDeviceInput(device: device) else {
|
let input = try? AVCaptureDeviceInput(device: device) else {
|
||||||
showToast("无法打开相机")
|
showToast("无法打开相机")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
captureSession.beginConfiguration()
|
||||||
|
defer { captureSession.commitConfiguration() }
|
||||||
|
|
||||||
guard captureSession.canAddInput(input) else { return }
|
guard captureSession.canAddInput(input) else { return }
|
||||||
captureSession.addInput(input)
|
captureSession.addInput(input)
|
||||||
|
|
||||||
@ -112,12 +127,30 @@ final class QRCodeScannerViewController: BaseViewController, AVCaptureMetadataOu
|
|||||||
layer.videoGravity = .resizeAspectFill
|
layer.videoGravity = .resizeAspectFill
|
||||||
view.layer.insertSublayer(layer, at: 0)
|
view.layer.insertSublayer(layer, at: 0)
|
||||||
previewLayer = layer
|
previewLayer = layer
|
||||||
|
isCameraConfigured = true
|
||||||
|
|
||||||
|
updatePreviewLayout()
|
||||||
|
startCaptureSessionIfNeeded()
|
||||||
|
}
|
||||||
|
|
||||||
|
private func updatePreviewLayout() {
|
||||||
|
previewLayer?.frame = view.bounds
|
||||||
|
}
|
||||||
|
|
||||||
|
private func startCaptureSessionIfNeeded() {
|
||||||
|
guard isCameraConfigured, !captureSession.isRunning else { return }
|
||||||
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
|
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
|
||||||
self?.captureSession.startRunning()
|
self?.captureSession.startRunning()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func stopCaptureSession() {
|
||||||
|
guard captureSession.isRunning else { return }
|
||||||
|
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
|
||||||
|
self?.captureSession.stopRunning()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func updateMask() {
|
private func updateMask() {
|
||||||
maskView.layer.sublayers?.forEach { $0.removeFromSuperlayer() }
|
maskView.layer.sublayers?.forEach { $0.removeFromSuperlayer() }
|
||||||
let border = CAShapeLayer()
|
let border = CAShapeLayer()
|
||||||
@ -139,7 +172,7 @@ final class QRCodeScannerViewController: BaseViewController, AVCaptureMetadataOu
|
|||||||
let value = object.stringValue,
|
let value = object.stringValue,
|
||||||
!value.isEmpty else { return }
|
!value.isEmpty else { return }
|
||||||
hasHandledResult = true
|
hasHandledResult = true
|
||||||
captureSession.stopRunning()
|
stopCaptureSession()
|
||||||
onScanResult?(value)
|
onScanResult?(value)
|
||||||
dismiss(animated: true)
|
dismiss(animated: true)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user