在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传给二维码生成器,具体步骤如下:
- 创建
DateFormatter实例,配置为只显示小时和分钟,格式为“HH mm”(24小时制)或“hh mm”(12小时制,按需调整) - 在生成二维码时,用该Formatter将
startTime转换为目标格式的字符串 - 将字符串转成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
相关产品推荐
相关产品推荐

