Joo*_*ila 7 foreach list swift swiftui
我想Section通过使用.onDelete修饰符在SwiftUI上实现“滑动到删除”功能。问题在于它总是删除列表中的第一项。
我的视图有一个列表,其中包含用创建的动态部分ForEach。
struct SetListView : View {
var setlist: Setlist
var body : some View {
List {
ForEach(setlist.sets) {
SetSection(number: $0.id, songs: $0.songs)
}
}
.listStyle(.grouped)
}
}
Run Code Online (Sandbox Code Playgroud)
在每个部分中,都有另一个ForEach创建动态行:
private struct SetSection : View {
var number: Int
@State var songs: [Song]
var body : some View {
Section (header: Text("Set \(number)"), footer: Spacer()) {
ForEach(songs) { song in
SongRow(song: song)
}
.onDelete { index in
self.songs.remove(at: index.first!)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
调试时,我发现的IndexSet是指当前部分而不是行。因此,从第一节删除项目时,总是删除第一项(因为第一节的索引为0)。
这是SwiftUI中的错误吗?
如果没有,那么我如何获得该行的索引?
简而言之,解决此问题的方法是通过以下方式将该部分传递给您的删除方法:
RandomAccessCollection您的源数据。ForEach然后在内部使用它ForEach,并将其传递给删除方法:List {
ForEach(someGroups.indices) { section in
bind(self.someGroups[section]) { someGroup in
Section(header: Text(someGroup.displayName)) {
ForEach(someGroup.numbers) { number in
Text("\(number)")
}
.onDelete { self.delete(at: $0, in: section) }
}
}
}
}
func delete(at offsets: IndexSet, in section: Int) {
print("\(section), \(offsets.first!)")
}
Run Code Online (Sandbox Code Playgroud)
import SwiftUI
func bind<Value, Answer>(_ value: Value, to answer: (Value) -> Answer) -> Answer { answer(value) }
struct Example: View {
struct SomeGroup: Identifiable, RandomAccessCollection {
typealias Indices = CountableRange<Int>
public typealias Index = Int;
var id: Int
var displayName: String
var numbers: [Int]
public var endIndex: Index {
return numbers.count - 1
}
public var startIndex: Index {
return 0
}
public subscript(position: Int) -> Int {
get { return numbers[position] }
set { numbers[position] = newValue }
}
}
var someGroups: [SomeGroup] = {
return [
SomeGroup(id: 0, displayName: "First", numbers: [1, 2, 3, 4]),
SomeGroup(id: 1, displayName: "Second", numbers: [1, 3, 5, 7])
]
}()
var body: some View {
List {
ForEach(someGroups.indices) { section in
bind(self.someGroups[section]) { someGroup in
Section(header: Text(someGroup.displayName)) {
ForEach(someGroup.numbers) { number in
Text("\(number)")
}
.onDelete { self.delete(at: $0, in: section) }
}
}
}
}
.listStyle(.grouped)
}
func delete(at offsets: IndexSet, in section: Int) {
print("\(section), \(offsets.first!)")
}
}
Run Code Online (Sandbox Code Playgroud)
非常感谢@ rob-mayoff,他通过Twitter为我指出了解决方案的正确方向!
我有完全一样的问题。事实证明,SwiftUI的(当前?)实现无法识别嵌套列表。这意味着,每个SetSection在你List被解释为单行,即使你有一个ForEach在它与实际SongRow秒。因此,IndexSet(index.first!)始终返回零。
我还注意到的是,即使使用诸如..
List {
Section {
ForEach(...) {
...
}
}
Section {
ForEach(...) {
...
}
}
}
Run Code Online (Sandbox Code Playgroud)
..个人行不能在节之间移动。当直接使用两个ForEach(即不使用Section包装器)时,也是如此。
我们可能应该针对每种现象提交报告。
| 归档时间: |
|
| 查看次数: |
683 次 |
| 最近记录: |