【发布时间】:2021-12-09 09:00:00
【问题描述】:
我有一个可能存在的父状态:
class Model: ObservableObject {
@Published var name: String? = nil
}
如果该状态存在,我想显示一个子视图。在本例中,显示name。
如果name 可见,我希望它可以显示并可编辑。我希望这是双向可编辑的,这意味着如果 Model.name 发生变化,我希望它推送到 ChildUI,如果 ChildUI 编辑它,我希望它反映到 Model.name。
但是,如果 Model.name 变为 nil,我希望 ChildUI 隐藏。
当我这样做时,通过解开Model.name,然后只有第一个值被现在控制该状态的Child 捕获。后续更改不会推送到上游,因为它不是Binding。
问题
如果存在可选,我可以将非可选上游绑定到可选吗? (这些词对吗?)
完整示例
import SwiftUI
struct Child: View {
// within Child, I'd like the value to be NonOptional
@State var text: String
var body: some View {
TextField("OK: ", text: $text).multilineTextAlignment(.center)
}
}
class Model: ObservableObject {
// within the parent, value is Optional
@Published var name: String? = nil
}
struct Parent: View {
@ObservedObject var model: Model = .init()
var body: some View {
VStack(spacing: 12) {
Text("Demo..")
// whatever Child loads the first time will retain
// even on change of model.name
if let text = model.name {
Child(text: text)
}
// proof that model.name changes are in fact updating other state
Text("\(model.name ?? "<waiting>")")
}
.onAppear {
model.name = "first change of optionality works"
loop()
}
}
@State var count = 0
func loop() {
async(after: 1) {
count += 1
model.name = "updated: \(count)"
loop()
}
}
}
func async(_ queue: DispatchQueue = .main,
after: TimeInterval,
run work: @escaping () -> Void) {
queue.asyncAfter(deadline: .now() + after, execute: work)
}
struct OptionalEditingPreview: PreviewProvider {
static var previews: some View {
Parent()
}
}
【问题讨论】:
-
如果我可能遗漏了一些关于正确的 SwiftUI 架构的东西,我也会感谢您提供指向涵盖此内容的文档或架构的指针