我已经在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)
}
}
}
答案 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