可选的 SwiftUI DatePicker 与 nil to Date 和 Date to nil 切换
Posted
技术标签:
【中文标题】可选的 SwiftUI DatePicker 与 nil to Date 和 Date to nil 切换【英文标题】:Optional SwiftUI DatePicker with nil to Date and Date to nil toggle 【发布时间】:2021-09-02 14:46:26 【问题描述】:我正在尝试构建一个可以处理可选日期的 DatePicker。
我使用this post 作为起点...但目前我的代码在nil
和Date()
之间切换几次后就崩溃了。
我怎样才能使这段代码安全?
import SwiftUI
extension Date
public var m3d2y4: String
let formatter = DateFormatter()
formatter.dateFormat = "MMM dd, yyyy"
return formatter.string(from: self)
struct OptionalDatePicker: View
@Binding var date: Date?
var nilText = "Never"
var nilDate = Date()
var body: some View
if let _ = date
datePicker
else
nilTextButton
private var dateBinding: Binding<Date>
Binding(get: date ?? nilDate , set: date = $0 )
private var dateString: String
dateBinding.wrappedValue.m3d2y4
private var nilTextButton: some View
Button(action: toggleDate)
Text(nilText)
private var datePicker: some View
ZStack
HStack
Text(dateString)
.foregroundColor(.blue)
Button(action: toggleDate() )
Image(systemName: "xmark.circle")
DatePicker("", selection: dateBinding, displayedComponents: [.date])
.opacity(0.02) // minimum opacity to still allow tapping
.labelsHidden()
private func toggleDate()
if let _ = date
date = nil
else
date = nilDate
struct OptionalDatePicker_Previews: PreviewProvider
static var previews: some View
ContentView()
struct ContentView: View
@State var date: Date? = nil
var body: some View
HStack
Text("Ends")
Spacer()
OptionalDatePicker(date: $date)
.padding()
提前致谢!
【问题讨论】:
你在这里做了一些奇怪的事情 -.opacity(0.02)
是一个原因。
选择器位于文本标签的前面,这样我仍然可以在点击时调出日历。如果opacity
设置为0
,它就不再是可点击的(不知道为什么?)...通过反复试验,我确定.opacity(0.02)
是仍然允许并捕获点击的最低值。如果DatePicker
有一个isPresented
参数,例如NavigationLink
,我认为我不需要这样做。
【参考方案1】:
注意到您在问题中链接到的 SO 帖子,我将在这里重复我的答案...
通过阅读Jim Dovey 的this blog,我几乎了解了有关 SwiftUI 绑定(使用核心数据)的所有知识。剩下的就是一些研究和几个小时的错误。
因此,当我使用 Jim 的技术在 SwiftUI Binding
上创建 Extensions
时,我们最终会得到类似这样的结果,以取消对 nil 的选择...
public extension Binding where Value: Equatable
init(_ source: Binding<Value>, deselectTo value: Value)
self.init(get: source.wrappedValue ,
set: source.wrappedValue = $0 == source.wrappedValue ? value : $0
)
然后可以像这样在整个代码中使用...
Picker("",
selection: Binding($date, deselectTo: nil),
displayedComponents: [.date]
)
...其中日期是可选的,例如...
@State private var date: Date?
【讨论】:
以上是关于可选的 SwiftUI DatePicker 与 nil to Date 和 Date to nil 切换的主要内容,如果未能解决你的问题,请参考以下文章
如何处理 swiftui @State optional unwrap
如何创建一个带有可选辅助 View 参数的 SwiftUI 视图?
如何使用 SwiftUI 和 Combine 检测 Datepicker 的值变化?