SwiftUI和UIkit方面的问题
我是初学者,应该用法方面的问题,已精简了程序,放入xcode就可运行。程序是一个年月日时分选择器,但是在月份改变的时候,日期始终是31天,没有改变。比如4月6月等都是30天。
我发现它取的是默认值,就是我初始化的值。
也做了调试,在此处打了断点(return parent.myDate.GetDays(yy: parent.myDate.year, mm: parent.myDate.month 这里是返回行数的),前三次是对的,后面三次就变成初始值了,也就是8月,8月就是31天,这是为什么?
还有点阴阳历切换的时候,选中的显示选中的都是数字,阴历应该输出“阴历”。
代码如下:
import SwiftUI
import UIKit
// `SimplePicker` 是一个 SwiftUI 视图,它使用 `UIViewRepresentable` 协议将 `UIPickerView` 包装成 SwiftUI 视图。
struct SimplePicker2: UIViewRepresentable {
@Binding var myDate: MyDateStruct2
// 创建并返回 `UIPickerView` 实例
func makeUIView(context: Context) -> UIPickerView {
let pickerView = UIPickerView()
pickerView.delegate = context.coordinator // 设置代理
pickerView.dataSource = context.coordinator // 设置数据源
// 初始化 selectedMonth
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 {
print("hello coordinator111")
return 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.myDate.maxYear - parent.myDate.minYear + 1
case 1: // 月
return 12
case 2: // 日
// 使用 selectedMonth 计算天数
// let month = selectedMonth
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.myDate.minYear)"
case 1: // 月
return parent.myDate.iflunar ? "阴历" : "\(row + 1)月"
case 2: // 日
return parent.myDate.iflunar ? "阴历" : "\(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:
// 更新 selectedMonth
parent.myDate.month = row + 1
let newDay = parent.myDate.GetDays(yy: parent.myDate.year, mm: parent.myDate.month)
if parent.myDate.day > newDay {
parent.myDate.day = newDay
}
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 iflunar: Bool = false
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("年月日时分-\(myDate.iflunar ? "阴历":"阳历")")
Text("\(String(myDate.year))年\(myDate.month)月\(myDate.day)日\(myDate.hour)时\(myDate.minute)分")
Button(action: {
myDate.year -= 1
myDate.iflunar.toggle()
}, label: {
Text("阴阳历")
})
SimplePicker2(myDate: $myDate)
.frame(height: 200) // 设置选择器的高度
}
}
}
// 预览 `TestView`
#Preview {
TestView2()
// SimplePicker()
}
我学习不久,求告知,多谢。