如果列表行在 SwiftUI 中包含文本字段,则无法从 foreach 中删除元素
Posted
技术标签:
【中文标题】如果列表行在 SwiftUI 中包含文本字段,则无法从 foreach 中删除元素【英文标题】:Cannot remove element from foreach if list row contains a textField in SwiftUI 【发布时间】:2020-12-13 21:12:00 【问题描述】:我已经阅读了几个解决这个问题的方法,我相信我根据建议做的正确,但是这个简单的代码仍然崩溃。
import SwiftUI
struct AnItem : Identifiable
let id = UUID()
var text: String
struct ContentView: View
@State private var items : [AnItem] = [AnItem(text: "A"), AnItem(text: "B"), AnItem(text: "C")]
var body: some View
List ()
ForEach (0 ..< items.count)
index in
TextField("test", text: $items[index].text)
.onDelete(perform: deleteItem)
private func deleteItem(at indexSet: IndexSet)
self.items.remove(atOffsets: indexSet)
任何人都有解决方法的想法,或者我可能只是做错了。崩溃说
Fatal error: Index out of range: file Swift/ContiguousArrayBuffer.swift, line 444
正如其他人所说,只是一个文本小部件就可以正常工作。这似乎是通过使用 TextField 引起的。
【问题讨论】:
您需要使用文本字段吗?或者我可以将其更改为更适合您的解决方案吗? 不,它需要是一个 TextField。我知道它适用于 Text。 【参考方案1】:这是一个可能的解决方案。使用id:\.id
识别项目,然后将 TextField 提取到另一个视图
struct AnItem : Identifiable
let id = UUID()
var text: String
struct ContentView: View
@State private var items : [AnItem] = [AnItem(text: "A"), AnItem(text: "B"), AnItem(text: "C")]
var body: some View
List
ForEach(items, id: \.id) item in
CustomTextField(item: item)
.onDelete(perform: deleteItem)
private func deleteItem(at indexSet: IndexSet)
items.remove(atOffsets: indexSet)
struct CustomTextField : View
@State var item : AnItem
var body : some View
TextField("Test", text: $item.text)
【讨论】:
这行得通。谢谢你。我不清楚这是 SwiftUI 应该如何工作还是这是一个错误。【参考方案2】:这样做怎么样:
首先让AnItem
符合Hashable
协议。
struct AnItem : Identifiable, Hashable
let id = UUID()
var text: String
现在让我们稍微改变一下Foreach
和List
:
List
ForEach (items, id: \.self) item in
Text("\(item.text)")
.onDelete(perform: deleteItem)
瞧!现在一切正常!
【讨论】:
OP 使用 TextField,而不是 Text。有区别 正确,问题是由我在应用程序中需要的 TextField 引起的。以上是关于如果列表行在 SwiftUI 中包含文本字段,则无法从 foreach 中删除元素的主要内容,如果未能解决你的问题,请参考以下文章