I'm using a two-column NavigationSplitView
. Trying to figure out how to update the data model via .onSubmit
modifier and use a TextField
view without Binding.constant
.
Within the detail
section, I have TextField
and TextEditor
.
- How to avoid
Binding.contant()
? I mean, I need mutation. - This is a correct way to update
value
property in Model?
I need a single selection in List.
Here's my sample code (70 line’s):
struct Model: Identifiable, Hashable {
var id = UUID()
var title: String = "Brand new"
var value: String = ""
func updateValue() async -> Model {
return Model(id: id, title: title, value: "The boar is running through the field happily")
}
}
final class DataModel: ObservableObject {
@Published
var models: [Model] = [
.init(title: "First", value: "fur"),
.init(title: "Second", value: "meow"),
.init(title: "Another", value: "Make SwiftUI, not war")
]
@MainActor
func updateModel(for model: Model.ID) async -> Void {
var findModel = models.first { $0.id == model }
findModel = await findModel?.updateValue()
}
}
struct ModelView: View {
@StateObject
private var dataModel = DataModel()
@State
private var listSelection: Model.ID?
private var selectedModel: Model? {
guard let selection = listSelection else { return nil }
return dataModel.models.first { $0.id == selection }
}
var body: some View {
NavigationSplitView {
List(dataModel.models, selection: $listSelection) { model in
NavigationLink(model.title, value: model.id)
}
} detail: {
if let selectedModel {
VStack {
TextField("Title", text: .constant(selectedModel.title))
.padding()
.background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 20))
.submitLabel(.go)
.onSubmit {
Task {
// Update Model.value by hit `Go`
await dataModel.updateModel(for: selectedModel.id)
}
}
TextEditor(text: .constant(selectedModel.value))
}
.padding()
.navigationTitle(selectedModel.title)
}
}
}
}
struct ModelView_Previews: PreviewProvider {
static var previews: some View {
ModelView()
.colorScheme(.light)
}
}