英文:
Binding’s inside NavigationSplitView detail (TextField, TextEditor)
问题
以下是您提供的代码的翻译部分:
我正在使用一个两列的`NavigationSplitView`。尝试找出如何通过`.onSubmit`修饰符来更新数据模型并使用`TextField`视图而不使用`Binding.constant`。
在`detail`部分中,我有`TextField`和`TextEditor`。
1. 如何避免使用`Binding.constant()`?我的意思是,我需要进行突变。
2. 更新Model中的`value`属性的正确方法是什么?
我需要在列表中进行单一选择。
这是我的示例代码(70行):
```swift
struct Model: Identifiable, Hashable {
var id = UUID()
var title: String = "全新的品牌"
var value: String = ""
func updateValue() async -> Model {
return Model(id: id, title: title, value: "野猪🐷正在快乐地奔跑在田野中")
}
}
final class DataModel: ObservableObject {
@Published
var models: [Model] = [
.init(title: "第一个", value: "毛皮"),
.init(title: "第二个", value: "喵喵"),
.init(title: "另一个", value: "创造SwiftUI,不是战争")
]
@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("标题", text: .constant(selectedModel.title))
.padding()
.background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 20))
.submitLabel(.go)
.onSubmit {
Task {
// 通过点击“Go”按钮更新Model.value
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)
}
}
请注意,代码中的引号已被翻译为中文,同时特殊字符如表情符号已保留在原文中。
英文:
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)
}
}
答案1
得分: 1
以下是代码部分的中文翻译:
struct Model: Identifiable, Hashable {
var id = UUID()
var title: String = "全新"
var value: String = ""
func updateValue() async -> Model {
return Model(id: id, title: title, value: "野猪 🐷 正在快乐地奔跑在田野上")
}
}
final class DataModel: ObservableObject {
@Published
var models: [Model] = [
.init(title: "第一个", value: "毛皮"),
.init(title: "第二个", value: "喵喵"),
.init(title: "另一个", value: "创造 SwiftUI,而不是战争")
]
@MainActor
func updateModel(for model: Binding<Model>) async -> Void {
model.wrappedValue = await model.wrappedValue.updateValue()
}
func bindingToModel(_ model: Model.ID) -> Binding<Model> {
Binding<Model> {
guard let index = self.models.firstIndex(where: { $0.id == model }) else {
return Model()
}
return self.models[index]
} set: { newModel in
guard let index = self.models.firstIndex(where: { $0.id == model }) else { return }
self.models[index] = newModel
}
}
}
struct ModelView: View {
@StateObject
private var dataModel = DataModel()
@State
private var listSelection: Model.ID?
var body: some View {
NavigationSplitView {
List(dataModel.models, selection: $listSelection) { model in
NavigationLink(model.title, value: model.id)
}
} detail: {
if let listSelection, let bindModel = dataModel.bindingToModel(listSelection) {
VStack {
TextField("标题", text: bindModel.title)
.padding()
.background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 20))
.submitLabel(.go)
.onSubmit {
Task {
// 通过点击“Go”按钮更新 Model.value
await dataModel.updateModel(for: bindModel)
}
}
TextEditor(text: bindModel.value)
}
.padding()
.navigationTitle(bindModel.title)
}
}
}
}
请注意,我已经将代码中的英文文本翻译成了中文。
英文:
After a couple of days, I realized what I could do.
No one answered the question, so I solved the problem this way.
The final solution is below:
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: Binding<Model>) async -> Void {
model.wrappedValue = await model.wrappedValue.updateValue()
}
func bindingToModel(_ model: Model.ID) -> Binding<Model> {
Binding<Model> {
guard let index = self.models.firstIndex(where: { $0.id == model }) else {
return Model()
}
return self.models[index]
} set: { newModel in
guard let index = self.models.firstIndex(where: { $0.id == model }) else { return }
self.models[index] = newModel
}
}
}
struct ModelView: View {
@StateObject
private var dataModel = DataModel()
@State
private var listSelection: Model.ID?
var body: some View {
NavigationSplitView {
List(dataModel.models, selection: $listSelection) { model in
NavigationLink(model.title, value: model.id)
}
} detail: {
if let listSelection, let bindModel = dataModel.bindingToModel(listSelection) {
VStack {
TextField("Title", text: bindModel.title)
.padding()
.background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 20))
.submitLabel(.go)
.onSubmit {
Task {
// Update Model.value by hit `Go`
await dataModel.updateModel(for: bindModel)
}
}
TextEditor(text: bindModel.value)
}
.padding()
.navigationTitle(bindModel.title)
}
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论