From 0964ef8b80a66112b8f917d654dddf32ec7ff7cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B1=89=E7=A7=8B?= <497055328@qq.com> Date: Tue, 7 Jul 2026 09:15:06 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=A6=96=E6=AC=A1=E6=8E=88?= =?UTF-8?q?=E4=BA=88=E7=9B=B8=E6=9C=BA=E6=9D=83=E9=99=90=E5=90=8E=E6=89=AB?= =?UTF-8?q?=E7=A0=81=E9=A1=B5=E9=BB=91=E5=B1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UI/Scan/QRCodeScannerViewController.swift | 43 ++++++++++++++++--- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/suixinkan/UI/Scan/QRCodeScannerViewController.swift b/suixinkan/UI/Scan/QRCodeScannerViewController.swift index fc10291..54c38e4 100644 --- a/suixinkan/UI/Scan/QRCodeScannerViewController.swift +++ b/suixinkan/UI/Scan/QRCodeScannerViewController.swift @@ -14,6 +14,7 @@ final class QRCodeScannerViewController: BaseViewController, AVCaptureMetadataOu private let captureSession = AVCaptureSession() private var previewLayer: AVCaptureVideoPreviewLayer? + private var isCameraConfigured = false private var hasHandledResult = false private let maskView = UIView() @@ -60,17 +61,21 @@ final class QRCodeScannerViewController: BaseViewController, AVCaptureMetadataOu checkCameraPermission() } + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + updatePreviewLayout() + startCaptureSessionIfNeeded() + } + override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() - previewLayer?.frame = view.bounds + updatePreviewLayout() updateMask() } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) - if captureSession.isRunning { - captureSession.stopRunning() - } + stopCaptureSession() } private func checkCameraPermission() { @@ -94,11 +99,21 @@ final class QRCodeScannerViewController: BaseViewController, AVCaptureMetadataOu } private func setupCamera() { + if isCameraConfigured { + updatePreviewLayout() + startCaptureSessionIfNeeded() + return + } + guard let device = AVCaptureDevice.default(for: .video), let input = try? AVCaptureDeviceInput(device: device) else { showToast("无法打开相机") return } + + captureSession.beginConfiguration() + defer { captureSession.commitConfiguration() } + guard captureSession.canAddInput(input) else { return } captureSession.addInput(input) @@ -112,12 +127,30 @@ final class QRCodeScannerViewController: BaseViewController, AVCaptureMetadataOu layer.videoGravity = .resizeAspectFill view.layer.insertSublayer(layer, at: 0) 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 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() { maskView.layer.sublayers?.forEach { $0.removeFromSuperlayer() } let border = CAShapeLayer() @@ -139,7 +172,7 @@ final class QRCodeScannerViewController: BaseViewController, AVCaptureMetadataOu let value = object.stringValue, !value.isEmpty else { return } hasHandledResult = true - captureSession.stopRunning() + stopCaptureSession() onScanResult?(value) dismiss(animated: true) }