如何在iOS 17中使用scrollPosition(id:)获取ScrollView中item的索引

问题描述 投票:0回答:1

iOS 17 引入的新 ScrollView 修饰符之一是

.scrollPosition(id:)
,它允许我们绑定滚动到视图的 ID。从Apple的文档中,我们可以这样做:

@Binding var items: [Item]
@Binding var scrollPosition: Item.ID?


ScrollView {
    LazyVStack {
        ForEach(items) { item in
            ItemView(item)
        }
    }
    .scrollTargetLayout()
}
.scrollPosition(id: $scrollPosition)

但是假设我们希望

scrollPosition
代表 item 中每个
items
index
。例如,当我们滚动到第一个
ItemView
时,
scrollPosition
应该为0;当我们滚动到第二个
ItemView
时,它应该是1,依此类推。

我们如何在 SwiftUI 中实现这一点(使用此修饰符)?

ios swiftui scrollview
1个回答
2
投票

尝试这种方法,声明

scrollPosition: Int?
, 在
items.enumerated()
循环中使用
ForEach
,以及
id(index)
,例如:

  @Binding var scrollPosition: Int?

  ForEach(Array(items.enumerated()), id: \.1.id) { index, item in
      ItemView(item).id(index)
  }

编辑-1:

这是我的答案完整的测试代码,展示了如何使用

.scrollPosition(id:...)
....scrollPosition represent the index of each item

struct ContentView: View {
    @State var items = [MyItem(name: "item-0"), MyItem(name: "item-1"), MyItem(name: "item-2"),
                        MyItem(name: "item-3"), MyItem(name: "item-4"), MyItem(name: "item-5"),
                        MyItem(name: "item-6"), MyItem(name: "item-7"), MyItem(name: "item-8")]
    
    @State var scrollPosition: Int?

    var body: some View {
        VStack {
            Text("\(scrollPosition ?? 0)")
            ScrollView {
                LazyVStack {
                    ForEach(Array(items.enumerated()), id: \.1.id) { index, item in
                        ItemView(item: item).id(index)
                    }
                }
                .scrollTargetLayout()
            }
            .scrollPosition(id: $scrollPosition)
        }
    }
}

struct ItemView: View {
    var item: MyItem

    var body: some View {
        ZStack {
            Rectangle()
                .fill(Color.green.gradient)
                .frame(height: 333)
            Text(item.name)
        }
    }
}

struct MyItem: Identifiable {
    let id = UUID()
    var name: String
}
© www.soinside.com 2019 - 2024. All rights reserved.