有没有办法在SwiftUI中删除列表中的行?

时间:2019-06-12 14:23:39

标签: swiftui

我已经在SwiftUI中创建了一个安静的简单列表,并希望使其可编辑,例如UIKit中的tableView。我想删除列表中所有已知手势的行(从右向左滑动)。

我尝试使用列表上方的按钮创建按钮,但是它看起来不太好,对于我的应用来说也不可行。

struct singleIsland: Identifiable {
    let id: Int
    let name:String
}

var islands = [
singleIsland(id: 0, name: "Wangerooge"),
singleIsland(id: 1, name: "Spiekeroog"),
singleIsland(id: 2, name: "Langeoog")
]

var body: some View {
    VStack {

        List(islands) { island in
            Text(island.name)
        }
    }
}

4 个答案:

答案 0 :(得分:4)

是的,使用SwiftUI非常简单。

正在更新代码...

struct SingleIsland: Identifiable {
    let id: Int
    let name:String
}

struct IslandListView: View {
    @State private var islands = [
        SingleIsland(id: 0, name: "Wangerooge"),
        SingleIsland(id: 1, name: "Spiekeroog"),
        SingleIsland(id: 2, name: "Langeoog")
    ]

    var body: some View {
        List {
            ForEach(islands.identified(by: \.name)) { island in
                Text(island.name)   
            }.onDelete(perform: delete)
        }
    }

    func delete(at offsets: IndexSet) {
        islands.remove(at: offsets)
    }
}

这将允许您滑动视图以删除行。

使用@State将视图设置为依赖于islands数组。对该阵列的任何更新都会触发视图重新加载。因此,通过从数组中删除一项,它将使更改对列表产生动画效果。

答案 1 :(得分:1)

将此添加到列表中:

.onDelete { $0.forEach { islands.remove(at: $0) } }

islands变成@State

之后

答案 2 :(得分:0)

$PSVariable = ${CFParameter}

write-host $PSVariable >> C:\temp\log.txt

将数据包装在struct SingleIsland { let name: String } struct ContentView: View { @State var islands = [ SingleIsland(name: "Wangerooge"), SingleIsland(name: "Spiekeroog"), SingleIsland(name: "Langeoog") ] var body: some View { List { ForEach(islands.identified(by: \.name)) { island in Text(island.name) }.onDelete(perform: delete) } } private func delete(with indexSet: IndexSet) { indexSet.forEach { islands.remove(at: $0) } } } 中,以确保视图更改后重绘。


注意

如果@State的构建方式如此,则会出现编译器错误:

List

它将抱怨List(data) { item in [...] } 不存在onDelete

我的解决方法是在List内使用ForEach,并在其上使用List函数。

答案 3 :(得分:-1)

您不能使用静态列表来做到这一点。

在现实世界中,您的岛屿列表可能总会来自视图外部。

我们使用您的结构:

[...]
struct singleIsland: Identifiable {
    var id: Int
    var name:String
}
[...]

并创建一个可绑定的对象来容纳这些岛

[...]
class IslandStore : BindableObject {

   let didChange = PassthroughSubject<IslandStore, Never>()

   var islands : [singleIsland] {
       didSet { didChange.send(self) }
   }

   init (islands: [singleIsland] = []){
       self.islands = islands
   } 
}
[...]

您需要导入合并以使用BindableObject

[...]
import SwiftUI
import Combine
[...]

您的视图现在绑定了岛屿商店 .onDelete(perform:delete)自动添加向左滑动以删除的功能。我们必须对删除功能进行编码:

[...]
struct ForTesting : View {
    @ObjectBinding var store = IslandStore()
    var body: some View {
        List {

            ForEach(store.islands) { island in
                Text(island.name)
                }.onDelete(perform: delete)

        }
    }

    func delete(at offsets: IndexSet) {

        // theres seems to be a bug that prevents us from using atOffsets
        // so we convert to index
        guard let index = Array(offsets).first else { return }

        store.islands.remove(at: index)
    }
}
[...]

,在此过程中,我们添加一个 EditButton()和一个标题。为此,我们必须将列表包装在 NavigationView

[...]
struct ForTesting : View {
    @ObjectBinding var store = IslandStore()
    var body: some View {
        NavigationView {
            List {

                ForEach(store.islands) { island in
                    Text(island.name)
                    }.onDelete(perform: delete)
                }
                .navigationBarTitle(Text("Islands"))
                .navigationBarItems(trailing: EditButton())

        }
    }

    func delete(at offsets: IndexSet) {

        // theres seems to be a bug that prevents us from using atOffsets
        // so we convert to index
        guard let index = Array(offsets).first else { return }

        store.islands.remove(at: index)
    }
}
[...]

更改DEBUG部分以初始化孤岛商店并将其移交给您的视图:

#if DEBUG

var islands = [
    singleIsland(id: 0, name: "Wangerooge"),
    singleIsland(id: 1, name: "Spiekeroog"),
    singleIsland(id: 2, name: "Langeoog"),
    singleIsland(id: 3, name: "Baltrum")
]

struct ForTesting_Previews : PreviewProvider {
    static var previews: some View {
        ForTesting(store: IslandStore(islands:islands))
    }
}

#endif

viewwithdelete

complete code