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

在Xcode SwiftUI中设置日期选择器生成指定格式二维码

问题描述

我已经实现了一个二维码生成器,希望将日期选择器选中的时间(仅小时和分钟)以“12 34”的格式嵌入二维码中。我已经实现了字符串类型的版本(可在Xcode中正常运行),但不知道如何处理日期时间类型的输入。

可运行的字符串类型实现代码

import Foundation
import SwiftUI
import CoreImage.CIFilterBuiltins

struct Generate: View {
    @State var start = String()
    let filter = CIFilter.qrCodeGenerator()
    let cont = CIContext()
    var body: some View {
        Image(uiImage: imageGenerate(start))
            .interpolation(.none)
            .resizable()
            .frame(width: 150, height: 150, alignment: .center)
    }
    func imageGenerate(_ start: String)-> UIImage {
        let data = Data(start.utf8)
        filter.setValue(data, forKey: "inputMessage")
        if let qr = filter.outputImage {
            if let qrImage = cont.createCGImage(qr, from: qr.extent){
                return UIImage(cgImage: qrImage)
            }
        }
        return UIImage(systemName: "xmark") ?? UIImage()
    }
}

(注:原代码中@State var start = String存在语法错误,已修正为@State var start = String();imageGenerate参数类型和Data初始化也做了对应修正)

无法运行的日期时间类型尝试代码

import Foundation
import SwiftUI
import CoreImage.CIFilterBuiltins

struct Generate: View {
    @State var start = Timer()
    let filter = CIFilter.qrCodeGenerator()
    let cont = CIContext()
    var body: some View {
        Image(uiImage: imageGenerate(start))
            .interpolation(.none)
            .resizable()
            .frame(width: 150, height: 150, alignment: .center)
    }
    func imageGenerate(_ start: Timer)-> UIImage {
        let data = Data(start.[not utf8, don't know what should it be?])
        filter.setValue(data, forKey: "inputMessage")
        if let qr = filter.outputImage {
            if let qrImage = cont.createCGImage(qr, from: qr.extent){
                return UIImage(cgImage: qrImage)
            }
        }
        return UIImage(systemName: "xmark") ?? UIImage()
    }
}

更新的日期选择器代码

@State private var startTime = Date()
@State private var sMinutes = 0
@State private var showflag = false
private let minutes = Array(0...59).map { String($0) }

var body: some View {
        Form{
            Section {
                VStack{
                    Text("请选择开始时间")
                        .padding(.bottom, 10)
                        .font(.system(size:20))
                        .bold()
                    DatePicker("", selection: $startTime, displayedComponents: .hourAndMinute)
                        .labelsHidden()
                        .datePickerStyle(.wheel)
                }
                
                VStack{
                    Picker(selection: $sMinutes, label: Text("请选择分钟数"))
                    {
                        ForEach(0 ..< minutes.count) {
                            index in Text(self.minutes[index]).tag(index)
                        }
                    }
                }
            }
            Button("完成"){
                self.showflag.toggle()
            }
            .font(.system(size:20))
            .bold()
            .foregroundColor(Color.blue)
            .frame(maxWidth: .infinity)
        }
}

(注:补全了原代码中缺失的@State变量和minutes数组定义,并做了中文翻译)


解决方案

核心思路是将Date类型的时间转换为指定格式的字符串,再转成Data传给二维码生成器,具体步骤如下:

  1. 创建DateFormatter实例,配置为只显示小时和分钟,格式为“HH mm”(24小时制)或“hh mm”(12小时制,按需调整)
  2. 在生成二维码时,用该Formatter将startTime转换为目标格式的字符串
  3. 将字符串转成UTF-8编码的Data,传入二维码生成器

以下是整合后的完整可运行代码:

import Foundation
import SwiftUI
import CoreImage.CIFilterBuiltins

struct TimeQRGeneratorView: View {
    @State private var startTime = Date()
    @State private var sMinutes = 0
    @State private var showflag = false
    private let minutes = Array(0...59).map { String($0) }
    
    // 二维码生成相关
    private let qrFilter = CIFilter.qrCodeGenerator()
    private let ciContext = CIContext()
    private let timeFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.dateFormat = "HH mm" // 24小时制,若要12小时制改为"hh mm"
        return formatter
    }()
    
    var body: some View {
        Form {
            Section {
                VStack {
                    Text("请选择开始时间")
                        .padding(.bottom, 10)
                        .font(.system(size: 20))
                        .bold()
                    DatePicker("", selection: $startTime, displayedComponents: .hourAndMinute)
                        .labelsHidden()
                        .datePickerStyle(.wheel)
                }
                
                VStack {
                    Picker(selection: $sMinutes, label: Text("请选择分钟数")) {
                        ForEach(0 ..< minutes.count) { index in
                            Text(self.minutes[index]).tag(index)
                        }
                    }
                }
            }
            
            Button("完成") {
                showflag.toggle()
            }
            .font(.system(size: 20))
            .bold()
            .foregroundColor(.blue)
            .frame(maxWidth: .infinity)
            
            // 点击完成后展示二维码
            if showflag {
                Section {
                    Image(uiImage: generateQRCode())
                        .interpolation(.none)
                        .resizable()
                        .scaledToFit()
                        .frame(width: 150, height: 150)
                }
            }
        }
    }
    
    private func generateQRCode() -> UIImage {
        // 将Date转为"HH mm"格式的字符串
        let timeString = timeFormatter.string(from: startTime)
        // 转成UTF-8 Data
        guard let data = timeString.data(using: .utf8) else {
            return UIImage(systemName: "xmark") ?? UIImage()
        }
        
        qrFilter.setValue(data, forKey: "inputMessage")
        guard let qrImage = qrFilter.outputImage,
              let cgImage = ciContext.createCGImage(qrImage, from: qrImage.extent) else {
            return UIImage(systemName: "xmark") ?? UIImage()
        }
        
        return UIImage(cgImage: cgImage)
    }
}

// 预览
struct TimeQRGeneratorView_Previews: PreviewProvider {
    static var previews: some View {
        TimeQRGeneratorView()
    }
}

关键说明

  • timeFormatter配置:使用en_US_POSIX避免区域设置影响格式,dateFormat设为"HH mm"确保输出“小时 分钟”的格式
  • 二维码生成逻辑:将格式化后的时间字符串转成UTF-8 Data,这是二维码生成器需要的标准输入格式
  • 界面整合:点击“完成”按钮后展示生成的二维码,逻辑更连贯

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 15:15:37