You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI扫码API展示列表后,如何添加按钮关闭视图返回根界面?

SwiftUI二维码扫描应用的两个问题:返回按钮无效与列表视图未铺满屏幕

我开发了一款基于SwiftUI的二维码扫描应用,扫描二维码后提取URL中的certificateNumber参数,调用API获取卡片数据并以列表视图展示。目前遇到两个问题:

  • 无法添加按钮关闭该层级列表视图返回根界面,尝试过网络上多种方案均无效;
  • 当前列表视图未铺满整个屏幕。

以下是我的实现代码:

import SwiftUI
import CodeScanner

extension URL {
    var components: URLComponents? {
        return URLComponents(url: self, resolvingAgainstBaseURL: false)
    }
}

extension Array where Iterator.Element == URLQueryItem {
    subscript(_ key: String) -> String? {
        return first(where: { $0.name == key })?.value
    }
}

struct Card: Decodable,Identifiable {
    let id = UUID()
    let sport: String
    let year: String
    let brand: String
    let cardNumber: String
    let playerName: String
    let extra: String
    let gradeName: String
    let grade: String
    let serial: String
    let authDate: String
}

class apiCall {
    func getUsers(apihit: String, completion:@escaping ([Card]) -> ()) {
        guard let apihit = URL(string: apihit) else { return }
        URLSession.shared.dataTask(with: apihit) { (data, _, _) in
            let users = try! JSONDecoder().decode([Card].self, from: data!)
            print(users)
            
            DispatchQueue.main.async {
                completion(users)
            }
        }
        .resume()
    }
}

struct ContentView: View {
    @State var isPresentingScanner = false
    @State var scannedCode: String = ""
    @State var users: [Card] = []


    var scannerSheet : some View {
        CodeScannerView(
            codeTypes: [.qr],
            completion: { result in
                if case let .success(code) = result {
                    self.scannedCode = code.string
                    self.isPresentingScanner = false
                }
            }
        )
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(.gray)
    }
    
    func getQueryStringParameter(url: String, param: String) -> String? {
      guard let url = URLComponents(string: url) else { return nil }
      return url.queryItems?.first(where: { $0.name == param })?.value
    }
    
    func getDateFromTimeStamp(timeStamp : Double) -> String {

            let date = NSDate(timeIntervalSince1970: timeStamp / 1000)
            
            let dayTimePeriodFormatter = DateFormatter()
            dayTimePeriodFormatter.dateFormat = "dd MMM YY, hh:mm a"

            let dateString = dayTimePeriodFormatter.string(from: date as Date)
            return dateString
        }

    var body: some View {

        VStack(spacing: 10) {
            
            Image("logo-white")
                .offset(y: -200)

            if let urlComponents = URL(string: scannedCode)?.components,
                let cert = urlComponents.queryItems?["certificateNumber"] {
                //Text(cert)

                let apihit = URL(string: "https://app.example.com/api.php?apikey=xxxx&cert=\(cert)")!
                NavigationView {
                    
                    List(users) { user in
                        Text("Set: " + user.year + " " + user.brand)
                            .font(.headline)
                        if !user.extra.isEmpty {
                            Text("Desc: " + user.extra)
                                .font(.headline)

                        }
                        Text("Player: " + user.playerName)
                            .font(.headline)
                        Text("Year: " + user.year)
                            .font(.headline)
                        Text("Sport: " + user.sport)
                            .font(.headline)
                        Text("Grade Name: " + user.gradeName)
                            .font(.headline)
                        Text("Grade: " + user.grade)
                            .font(.headline)
                        Text("Card Serial: " + user.serial)
                            .font(.headline)
                        Text("Authenticated: " + user.authDate)
                            .font(.headline)
                    }

                    
                    .onAppear {
                        apiCall().getUsers(apihit: apihit.absoluteString) { (users) in
                            self.users = users
                        }
                    }
                    .navigationTitle("Certificate Verification")
                }
            }
            
            
            Button("Scan QR Code") {
                self.isPresentingScanner = true
            }
            
            .padding()
            .background(Color(red: 0, green: 0, blue: 0.5))
            .foregroundColor(.white)
            .clipShape(Rectangle())
            .cornerRadius(20)
            
            .sheet(isPresented: $isPresentingScanner) {
                self.scannerSheet
                Button("Close") {
                    self.isPresentingScanner = false
                }
                .padding()
                .background(Color(red: 0, green: 0, blue: 0.5))
                .foregroundColor(.white)
                .clipShape(Rectangle())
                .cornerRadius(20)
            }
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(.gray)
        
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

附视图截图:
扫描后导航视图效果

内容的提问来源于stack exchange,提问作者Darryl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 16:20:21