这是swift UI方面的问题
这是实现年月日时分的选择器,问题是不论月份如何改变,日期始终是31天。调试的时候我发现日期会变成默认值也就是当前的时间8月1号,8月可不是31吗?
贴代码:
import SwiftUI
import UIKit
// `SimplePicker` 是一个 SwiftUI 视图,它使用 `UIViewRepresentable` 协议将 `UIPickerView` 包装成 SwiftUI 视图。
struct SimplePicker2: UIViewRepresentable {
@Binding var myDate: MyDateStruct2
let minYear: Int = 1900
let maxYear: Int = 2100
// 创建并返回 `UIPickerView` 实例
func makeUIView(context: Context) -> UIPickerView {
let pickerView = UIPickerView()
pickerView.delegate = context.coordinator // 设置代理
pickerView.dataSource = context.coordinator // 设置数据源
pickerView.selectRow(myDate.year - myDate.minYear, inComponent: 0, animated: false)
pickerView.selectRow(myDate.month - 1, inComponent: 1, animated: false)
pickerView.selectRow(myDate.day - 1, inComponent: 2, animated: false)
pickerView.selectRow(myDate.hour - 1, inComponent: 3, animated: false)
pickerView.selectRow(myDate.minute - 1, inComponent: 4, animated: false)
return pickerView
}
// 当 SwiftUI 需要更新视图时调用,这里不需要更新视图,所以为空实现
func updateUIView(_ uiView: UIPickerView, context: Context) {
uiView.reloadAllComponents()
uiView.selectRow(myDate.year - myDate.minYear, inComponent: 0, animated: false)
uiView.selectRow(myDate.month - 1, inComponent: 1, animated: false)
uiView.selectRow(myDate.day - 1, inComponent: 2, animated: false)
uiView.selectRow(myDate.hour - 1, inComponent: 3, animated: false)
uiView.selectRow(myDate.minute - 1, inComponent: 4, animated: false)
}
// 创建并返回 `Coordinator` 实例
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
// `Coordinator` 类负责处理 `UIPickerView` 的委托和数据源方法
class Coordinator: NSObject, UIPickerViewDelegate, UIPickerViewDataSource {
var parent: SimplePicker2
// 初始化 `Coordinator` 实例,保存对 `SimplePicker` 的引用
init(_ pickerView: SimplePicker2) {
self.parent = pickerView
}
// 返回选择器的列数 年月日时分 所有五列
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 5 // parent.data.count
}
// 返回某列的行数
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
switch component {
case 0: // 年
return parent.maxYear - parent.minYear + 1
case 1: // 月
return 12
case 2: // 日
return parent.myDate.GetDays(yy: parent.myDate.year, mm: parent.myDate.month)
case 3: // 时
return 24
case 4: // 分
return 60
default: // 秒或者错误 其实没有秒的
return 60
}
}
// 返回某列某行的标题
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
switch component {
case 0: // 年
return "\(row + parent.minYear)"
case 1: // 月
return "\(row + 1)月"
case 2: // 日
return "\(row + 1)日"
case 3: // 时
return "\(row)"
case 4: // 分
return "\(row)"
default: // 秒或者错误 其实没有秒的
return "\(row)"
}
}
// 处理选择事件,打印选择的值
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
switch component {
case 0:
parent.myDate.year = row + parent.myDate.minYear
case 1:
parent.myDate.month = row + 1
pickerView.reloadComponent(2)
print("月份改变:\(row + 1)-\(parent.myDate.month)")
case 2:
parent.myDate.day = row + 1
case 3:
parent.myDate.hour = row
case 4:
parent.myDate.minute = row
default:
break
}
}
// 设置宽度
public func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
let totalWidth = pickerView.bounds.width
switch component {
case 0:
return totalWidth * 0.24 // 第一列宽度为100
case 1:
return totalWidth * 0.21 // 第二列宽度为150
case 2:
return totalWidth * 0.23 // 第三列宽度为200
case 3:
return totalWidth * 0.15
default:
return totalWidth * 0.15
}
}
}
}
struct MyDateStruct2 {
var minYear = 1900
var maxYear = 2100
var year: Int = 2000 // 阳历
var month: Int = 1
var day: Int = 1
var hour: Int = 0
var minute: Int = 0
func GetDays(yy: Int, mm: Int) -> Int {
if mm < 1 || mm > 12 {
return 0
}
if yy == 1582 && mm == 10 {
return 21
}
// 计算是否是闰年
let isLeapYear = (yy % 4 == 0 && yy % 100 != 0) || (yy % 400 == 0)
// 每月的天数
let daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
// 计算该月的天数
var dom = daysInMonth[mm - 1]
if mm == 2 && isLeapYear {
dom = 29
}
return dom
}
}
// `TestView` 是一个包含 `SimplePicker` 的 SwiftUI 视图
struct TestView2: View {
@State private var myDate: MyDateStruct2
init() {
let calendar = Calendar.current
let now = Date()
let components = calendar.dateComponents([.year, .month, .day, .hour, .minute], from: now)
_myDate = State(initialValue: MyDateStruct2(
year: components.year!,
month: components.month!,
day: components.day!,
hour: components.hour!,
minute: components.minute!))
}
var body: some View {
VStack {
Text("年月日时分")
Text("\(String(myDate.year))年\(myDate.month)月\(myDate.day)日\(myDate.hour)时\(myDate.minute)分")
Button(action: {
myDate.year -= 1
}, label: {
Text("阴阳历")
})
SimplePicker2(myDate: $myDate)
.frame(height: 200) // 设置选择器的高度
}
}
}
// 预览 `TestView`
#Preview {
TestView2()
// SimplePicker()
}
我在
```swift
return parent.myDate.GetDays(yy: parent.myDate.year, mm: parent.myDate.month)
```加了断点,选择日期后,我发现它执行了6次,前三次时间都是对的,后面日期不对了,变成了默认值也就是2024.8.1号。
问题出在哪里?请求帮助,谢谢您!