我正在试验https://alanquatermain.me/programming/swiftui/2019-11-15-CoreData-and-bindings/中的代码
我的目标是让DatePicker绑定到Binding〈Date?〉,它允许空值而不是初始化到Date();如果您核心数据模型实体中有Date属性,且该属性接受nil作为有效值,那么这将非常有用。
下面是我的swiftPlayground代码:
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)
我找不到解决方案来修复此代码。它在切换第一次切换到打开时工作,但在切换关闭时崩溃。
删除DatePicker后,代码似乎运行正常,并将代码更改为以下代码:
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)
我怀疑和这部分密码有关
DatePicker("Due Date", selection: Binding($testDate)!, displayedComponents: .date )
或
将源.wrappedValue设置回nil时出现问题(请参阅绑定扩展)
4条答案
按热度按时间aiqt4smr1#
大多数可选绑定问题都可以通过以下方式解决:
下面是我如何使用它与DatePicker:
eh57zj3b2#
问题是
DatePicker
抓取绑定,并且由于Toggle
操作,即使您将其从视图中删除,也不会很快释放它,因此它在强制展开可选时崩溃,变为nil ...这次崩溃的解决方案是
axzmvihb3#
我在所有SwiftUI拾取器中使用的替代解决方案...
我通过逐个阅读Jim Dovey了解了我所知道的关于SwiftUI绑定(带核心数据)的几乎所有知识。剩下的是一些研究和相当多的几个小时犯错误的结合。
因此,当我使用Jim的技术在SwiftUI
Binding
上创建Extensions
时,我们最终会得到这样的结果,即取消选择为零...然后可以像这样在整个代码中使用...
或使用
.pickerStyle(.segmented)
时...这会根据
UISegmentedControl
和selectedSegmentIndex
的文档将分段样式选取器的index
设置为-1。默认值为noSegment(不选择任何段),直到用户触摸某个段。将此属性设置为-1可关闭当前选择。
63lcw9qa4#
这是我的解决方案,我添加了一个按钮来删除日期并添加默认日期。所有这些都被 Package 在一个新组件中
https://gist.github.com/Fiser12/62ef54ba0048e5b62cf2f2a61f279492