【问题标题】:Editbutton deletes items (with Bindings) from List in a funny way in SwiftUIEditbutton 在 SwiftUI 中以一种有趣的方式从 List 中删除项目(带有绑定)
【发布时间】:2021-04-25 07:54:24
【问题描述】:

我放弃了。这就是问题所在:我尝试将数组names 作为 ObservableObject 加载到我的列表中。名称必须以 Bindings 的形式连接到 TextField:

class Users: ObservableObject {
    @Published var names = ["Adele", "Taylor", "Michael"]
}

我的 ContentView 如下所示:

@EnvironmentObject var users: Users
var body: some View {
    NavigationView {
        List {
            ForEach(0..<users.names.count, id: \.self) {
                TextField("titel", text: $users.names[$0])
            }
            .onDelete(perform: delete)
        }
        .navigationBarItems(trailing: EditButton())
        .navigationTitle("bug")
    }
}
func delete(at offsets: IndexSet) {
    users.names.remove(atOffsets: offsets)
}

environmentObject 链接到 ContentView():

ContentView()
.environmentObject(Users())

一切正常,但是当我尝试删除一行时,它看起来很有趣:下面的行向右滑动,应该删除的行向上移动。它甚至不一致,但取决于我开始删除的项目。看到这个.gif:

到目前为止我尝试过的:

我认为该错误与无法识别的列表有关。所以我尝试使用类似的东西:

ForEach(users.names, id: \.id) {
    ...
}

使用带有id: UUID() 的新用户类 但是使用对象本身而不是0..&lt;users.names.count 只会导致问题,即我不能在我的 ForEach-Loop 中使用绑定。也可以看看: @Binding and ForEach in SwiftUI

所以我的问题是:

  • 我在这里错过了什么吗?我是 SwiftUI 的新手,所以我很有可能没有掌握基本知识。
  • 我可以在 ForEach-Loop 中使用绑定,同时使用 UUID 作为 id(不是id: \.self)吗?
  • 我能否使 ForEach-Loop 中的项目如此可识别,以便在删除它们的同时使用 ForEach(0..&lt;users.names.count, id: \.self) 时不会出现视觉错误?

【问题讨论】:

    标签: swift binding swiftui swiftui-list observableobject


    【解决方案1】:

    您可以使用enumerated 访问element 及其index

    ForEach(Array(users.names.enumerated()), id: \.element.id) { index, element in
        // use either `index` or `element` here
    }
    

    您还可以使用此extension 来确保您在删除项目时不会访问不存在的绑定。

    【讨论】:

    • 他们的Binding 看起来像:Binding&lt;String&gt;(get: { element }, set: { users.names[index] = $0 })
    • 非常感谢!我需要两个提示才能让它发挥作用。
    【解决方案2】:

    @pawello@George_E 的帮助下,我的工作代码现在看起来像这样:

    struct UserWithUUID: Identifiable {
        var id: UUID
        var name: String
    }
    
    class Users: ObservableObject {
        @Published var names = [UserWithUUID(id: UUID(), name: "Taylor"), UserWithUUID(id: UUID(), name: "Swift")]
    }
    
    struct ContentView: View {
        @EnvironmentObject var users: Users
        
        var body: some View {
            NavigationView {
                List {
                    ForEach(Array(users.names.enumerated()), id: \.element.id) { index, element in
                        TextField("titel", text: Binding<String>(get: { element.name }, set: { users.names[index].name = $0 }))
                    }
                    .onDelete(perform: delete)
                }
                .navigationBarItems(trailing: EditButton())
                .navigationTitle("working")
            }
        }
        func delete(at offsets: IndexSet) {
            users.names.remove(atOffsets: offsets)
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-05-08
      • 1970-01-01
      • 2019-11-19
      • 2013-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-28
      • 1970-01-01
      相关资源
      最近更新 更多