我尝试通过按钮以编程方式在 MultiDatePicker 中选择日期(今天)。选择按预期进行,并且将调用 onChange 修饰符,并且今天在选取器中标记为已选择。但是,当我尝试直接在 MultiDatePicker 中取消选择日期时,日期不再被标记,但 onChange 修饰符将不会被调用。如果您现在点击 MultiDatePicker 中的另一个日期,则两个日期、另一个日期和今天的日期都将标记为已选择。
import SwiftUI
struct ContentView: View {
@Environment(\.calendar) private var calendar
@State private var selectedDates: Set<DateComponents> = []
@State private var onChangeCounter = 0
var body: some View {
VStack {
MultiDatePicker("Select dates", selection: $selectedDates)
.frame(height: UIScreen.main.bounds.width)
.onChange(of: selectedDates) { _ in
self.onChangeCounter += 1
}
Button("Select today") {
let todayDatecomponents = calendar.dateComponents(in: calendar.timeZone, from: Date.now)
selectedDates.insert(todayDatecomponents)
}
.foregroundColor(.white)
.frame(minWidth: 150)
.padding()
.background(Color.accentColor)
.cornerRadius(20)
HStack {
Text("onChangeCounter")
Spacer()
Text(String(onChangeCounter))
}
.padding()
Spacer()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Run Code Online (Sandbox Code Playgroud)
我是否做错了什么,或者是否无法以编程方式在 MultiDatePicker 中选择日期?
谢谢你!
就本次讨论而言,今天是指2022 年 12 月 17 日
问题是Date.now不等于今天
我在美国东海岸时区...如果我添加一个按钮print(Date.now)并点击它,我会在调试控制台中看到以下内容:
2022-12-17 14:08:52 +0000
Run Code Online (Sandbox Code Playgroud)
如果我 4 秒后再次点击它,我会看到以下内容:
2022-12-17 14:08:56 +0000
Run Code Online (Sandbox Code Playgroud)
这两个日期不相等。
那么,让我们看看MultiDatePicker它的用途是什么selection。
将你的更改MultiDatePicker为:
MultiDatePicker("Select dates", selection: $selectedDates)
.frame(height: UIScreen.main.bounds.width)
.onChange(of: selectedDates) { _ in
print("onChange")
selectedDates.forEach { d in
print(d)
}
print()
self.onChangeCounter += 1
}
Run Code Online (Sandbox Code Playgroud)
如果我运行该应用程序并选择 12 月 14 日、19 日和 8 日,我会看到以下内容:
onChange
calendar: gregorian (current) era: 1 year: 2022 month: 12 day: 14 isLeapMonth: false
onChange
calendar: gregorian (current) era: 1 year: 2022 month: 12 day: 14 isLeapMonth: false
calendar: gregorian (current) era: 1 year: 2022 month: 12 day: 19 isLeapMonth: false
onChange
calendar: gregorian (current) era: 1 year: 2022 month: 12 day: 14 isLeapMonth: false
calendar: gregorian (current) era: 1 year: 2022 month: 12 day: 19 isLeapMonth: false
calendar: gregorian (current) era: 1 year: 2022 month: 12 day: 8 isLeapMonth: false
Run Code Online (Sandbox Code Playgroud)
现在,我取消选择第 19 个,然后我看到:
onChange
calendar: gregorian (current) era: 1 year: 2022 month: 12 day: 14 isLeapMonth: false
calendar: gregorian (current) era: 1 year: 2022 month: 12 day: 8 isLeapMonth: false
Run Code Online (Sandbox Code Playgroud)
19号已正确从 中删除Set。
现在,我点击“选择今天”按钮,我看到了:
onChange
calendar: gregorian (current) era: 1 year: 2022 month: 12 day: 14 isLeapMonth: false
calendar: gregorian (current) era: 1 year: 2022 month: 12 day: 8 isLeapMonth: false
calendar: gregorian (current) timeZone: America/New_York (fixed (equal to current)) era: 1 year: 2022 month: 12 day: 17 hour: 9 minute: 24 second: 11 nanosecond: 339460015 weekday: 7 weekdayOrdinal: 3 quarter: 0 weekOfMonth: 3 weekOfYear: 51 yearForWeekOfYear: 2022 isLeapMonth: false
Run Code Online (Sandbox Code Playgroud)
正如我们所看到的,这两行:
let todayDatecomponents = calendar.dateComponents(in: calendar.timeZone, from: Date.now)
selectedDates.insert(todayDatecomponents)
Run Code Online (Sandbox Code Playgroud)
插入一个包含更多DateComponents细节的对象。
如果我再次点击“选择今天”,我会得到以下信息:
onChange
calendar: gregorian (current) era: 1 year: 2022 month: 12 day: 8 isLeapMonth: false
calendar: gregorian (current) era: 1 year: 2022 month: 12 day: 14 isLeapMonth: false
calendar: gregorian (current) timeZone: America/New_York (fixed (equal to current)) era: 1 year: 2022 month: 12 day: 17 hour: 9 minute: 24 second: 11 nanosecond: 339460015 weekday: 7 weekdayOrdinal: 3 quarter: 0 weekOfMonth: 3 weekOfYear: 51 yearForWeekOfYear: 2022 isLeapMonth: false
calendar: gregorian (current) timeZone: America/New_York (fixed (equal to current)) era: 1 year: 2022 month: 12 day: 17 hour: 9 minute: 26 second: 39 nanosecond: 866878032 weekday: 7 weekdayOrdinal: 3 quarter: 0 weekOfMonth: 3 weekOfYear: 51 yearForWeekOfYear: 2022 isLeapMonth: false
Run Code Online (Sandbox Code Playgroud)
现在selectedDates包含两个“今天日期”...相隔 2 分钟 28 秒。
当我点击日历上的 17 号时,其中没有set要删除的匹配日期...因此当日历刷新时(例如当我选择另一个日期时),17 号仍然显示为选定的。
因此,让我们更改以编程方式插入的内容DateComponents以匹配日历的数据:
let todayDatecomponents = calendar.dateComponents([.calendar, .era, .year, .month, .day], from: Date.now)
selectedDates.insert(todayDatecomponents)
Run Code Online (Sandbox Code Playgroud)
现在,当我们点击17日历时,它将被取消选择,并且匹配的对象selectedDates将被删除。
以下是我修改您的代码以进行调试的方法:
import SwiftUI
@available(iOS 16.0, *)
struct MultiDateView: View {
@Environment(\.calendar) private var calendar
@State private var selectedDates: Set<DateComponents> = []
@State private var onChangeCounter = 0
var body: some View {
VStack {
MultiDatePicker("Select dates", selection: $selectedDates)
.frame(height: UIScreen.main.bounds.width)
.onChange(of: selectedDates) { _ in
print("onChange")
selectedDates.forEach { d in
print(d)
}
print()
self.onChangeCounter += 1
}
Button("Select today") {
let todayDatecomponents = calendar.dateComponents(in: calendar.timeZone, from: Date.now)
selectedDates.insert(todayDatecomponents)
}
.foregroundColor(.white)
.frame(minWidth: 150)
.padding()
.background(Color.accentColor)
.cornerRadius(20)
Button("Select today the right way") {
let todayDatecomponents = calendar.dateComponents([.calendar, .era, .year, .month, .day], from: Date.now)
selectedDates.insert(todayDatecomponents)
}
.foregroundColor(.white)
.frame(minWidth: 150)
.padding()
.background(Color.green)
.cornerRadius(20)
HStack {
Text("onChangeCounter")
Spacer()
Text(String(onChangeCounter))
}
.padding()
Button("Print Date.now in debug console") {
print("debug")
print("debug:", Date.now)
print()
}
.foregroundColor(.white)
.frame(minWidth: 150)
.padding()
.background(Color.red)
.cornerRadius(20)
Spacer()
}
}
}
@available(iOS 16.0, *)
struct MultiDateView_Previews: PreviewProvider {
static var previews: some View {
MultiDateView()
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
393 次 |
| 最近记录: |