使用swiftui实现打开摄像头扫描二维码功能,如果二维码是网址,就加载网站,如果不是网址,就显示扫到的内容

首先,需要创建一个自定义的 UIViewControllerRepresentable 来使用 AVCaptureSession 扫描二维码。使用UIApplication.shared.canOpenURL(url)来判断是否可以打开扫描到的内容,可以的话就使用WKWebView加载扫描到的网址,不可以的话,就显示出来扫描的什么内容。

注意:在使用这个代码之前一定要加摄像头权限,如果要访问相册,还要添加相册权限,添加权限的文章:https://xiaoshen.blog.csdn.net/article/details/141218299

1. 创建扫描二维码的 ScannerView

首先,需要创建一个自定义的 UIViewControllerRepresentable 来使用 AVCaptureSession 扫描二维码。

import SwiftUI
import AVFoundation

struct ScannerView: UIViewControllerRepresentable {
    class Coordinator: NSObject, AVCaptureMetadataOutputObjectsDelegate {
        var parent: ScannerView

        init(parent: ScannerView) {
            self.parent = parent
        }

        func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
            if let metadataObject = metadataObjects.first {
                guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else { return }
                guard let stringValue = readableObject.stringValue else { return }
                AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
                parent.didFindCode(stringValue)
            }
        }
    }

    var didFindCode: (String) -> Void

    func makeCoordinator() -> Coordinator {
        return Coordinator(parent: self)
    }

    func makeUIViewController(context: Context) -> UIViewController {
        let viewController = UIViewController()
        let captureSession = AVCaptureSession()

        guard let videoCaptureDevice = AVCaptureDevice.default(for: .video) else { return viewController }
        let videoInput: AVCaptureDeviceInput

        do {
            videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)
        } catch {
            return viewController
        }

        if captureSession.canAddInput(videoInput) {
            captureSession.addInput(videoInput)
        } else {
            return viewController
        }

        let metadataOutput = AVCaptureMetadataOutput()

        if captureSession.canAddOutput(metadataOutput) {
            captureSession.addOutput(metadataOutput)

            metadataOutput.setMetadataObjectsDelegate(context.coordinator, queue: DispatchQueue.main)
            metadataOutput.metadataObjectTypes = [.qr]
        } else {
            return viewController
        }

        let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        previewLayer.frame = viewController.view.layer.bounds
        previewLayer.videoGravity = .resizeAspectFill
        viewController.view.layer.addSublayer(previewLayer)

        captureSession.startRunning()

        return viewController
    }

    func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
}

2. 创建 WebView

接下来,创建一个简单的 WebView 来加载网址。

import SwiftUI
import WebKit

struct WebView: UIViewRepresentable {
    let url: URL

    func makeUIView(context: Context) -> WKWebView {
        return WKWebView()
    }

    func updateUIView(_ uiView: WKWebView, context: Context) {
        let request = URLRequest(url: url)
        uiView.load(request)
    }
}

3. 主视图 ContentView

最后,创建主视图来处理扫描到的结果。如果结果是网址,则显示 WebView,否则显示二维码的内容。

import SwiftUI

struct ContentView: View {
    // 扫描二维码并加载网站
    @State private var scannedCode: String? = nil
    @State private var isShowingScanner = false

    var body: some View {
        VStack {
            if let code = scannedCode, let url = URL(string: code), UIApplication.shared.canOpenURL(url) {
                WebView(url: url)
            } else if let code = scannedCode {
                Text("Scanned Code: \(code)")
                    .padding()
            } else {
                Button(action: {
                    isShowingScanner = true
                }) {
                    Text("Scan QR Code")
                        .font(.headline)
                        .padding()
                        .background(Color.blue)
                        .foregroundColor(.white)
                        .cornerRadius(10)
                }
                .sheet(isPresented: $isShowingScanner) {
                    ScannerView { code in
                        self.scannedCode = code
                    }
                    .edgesIgnoringSafeArea(.all)
                }
            }
        }
    }
}

@main
struct QRCodeScannerApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

最后的效果如下:

  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

1024小神

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值