I'm experimenting code from https://alanquatermain.me/programming/swiftui/2019-11-15-CoreData-and-bindings/
my goal is to have DatePicker bind to Binding< Date? > which allow for nil value instead of initiate to Date(); this is useful, if you have Date attribute in your core data model entity which accept nil as valid value.
Here is my swift playground code:
extension Binding {
init<T>(isNotNil source: Binding<T?>, defaultValue: T) where Value == Bool {
self.init(get: { source.wrappedValue != nil },
set: { source.wrappedValue = $0 ? defaultValue : nil})
}
}
struct LiveView: View {
@State private var testDate: Date? = nil
var body: some View {
VStack {
Text("abc")
Toggle("Has Due Date",
isOn: Binding(isNotNil: $testDate, defaultValue: Date()))
if testDate != nil {
DatePicker(
"Due Date",
selection: Binding($testDate)!,
displayedComponents: .date
)
}
}
}
}
let liveView = LiveView()
PlaygroundPage.current.liveView = UIHostingController(rootView: liveView)
I can't find solution to fix this code. It works when the toggle first toggled to on, but crash when the toggle turned back off.
The code seems to behave properly when I removed the DatePicker, and change the code to following:
extension Binding {
init<T>(isNotNil source: Binding<T?>, defaultValue: T) where Value == Bool {
self.init(get: { source.wrappedValue != nil },
set: { source.wrappedValue = $0 ? defaultValue : nil})
}
}
struct LiveView: View {
@State private var testDate: Date? = nil
var body: some View {
VStack {
Text("abc")
Toggle("Has Due Date",
isOn: Binding(isNotNil: $testDate, defaultValue: Date()))
if testDate != nil {
Text("(testDate!)")
}
}
}
}
let liveView = LiveView()
PlaygroundPage.current.liveView = UIHostingController(rootView: liveView)
I suspect it's something to do with this part of the code
DatePicker("Due Date", selection: Binding($testDate)!, displayedComponents: .date )
or
problem when the source.wrappedValue set back to nil (refer to Binding extension)
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…