点击日期时是否可以关闭 DatePicker 的日历?

Chr*_*zak 8 datepicker swiftui

我有一个基本的 SwiftUI 日期选择器,点击时会显示日历小部件:

DatePicker(
  "Date",
  selection: $date,
  in: ...Date(),
  displayedComponents: [.date]
)
Run Code Online (Sandbox Code Playgroud)

扩展日历

当您选择一个日期(上例中的 10 月 8 日)时,日历仍保留在屏幕上,为了折叠它,您需要点击日历外部。

是否可以在选择日期时自动折叠它?

Chr*_*zak 10

我最终得到了一个相当老套的解决方案,似乎可以完成这项工作。

添加一个@State保存日历 ID 的变量:

@State private var calendarId: Int = 0
Run Code Online (Sandbox Code Playgroud)

DatePicker使用.id.onChange 和 .onTapGesture操作链接调用:

DatePicker(
  "Date", selection: $date, in: ...Date(), displayedComponents: [.date]
)
.id(calendarId)
.onChange(of: date) { _ in
  calendarId += 1
})
Run Code Online (Sandbox Code Playgroud)

Xcode 15 更新(2023 年 11 月)

在 Xcode 版本 < 15 中,您可能还需要.onTapGesture对上述内容执行操作:

.onTapGesture {
  calendarId += 1
}
Run Code Online (Sandbox Code Playgroud)

但在 Xcode 15 中,这似乎会导致以下崩溃:

此 UITargetedPreview 初始值设定项要求视图位于窗口中,但事实并非如此。要么解决这个问题,要么使用另一个带有目标的初始化器。

  • 从 Xcode 13.2 / iOS 15 开始,.onTapGesture 给我留下了 NSInternalInconsistencyException。然而,忽略它对我来说效果很好。 (2认同)

Jas*_*rth 5

@chris.kobrzak 提供了一个很好的方向,我最终用以下方法解决了这个问题:

struct ContentView: View {
    @State var calendarId: UUID = UUID()
    @State var someday: Date = Date()
    
    var body: some View {
        VStack {
            DatePicker("Day", selection: $someday, displayedComponents: [.date])
                .labelsHidden()
                .id(calendarId)
                .onChange(of: whatday) { _ in
                    calendarId = UUID()
                }
            AnotherView(someday)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)