Scroll 我如何正确地通过a";单元格项目“;从迅捷懒散的网格到一张.sheet?

Scroll 我如何正确地通过a";单元格项目“;从迅捷懒散的网格到一张.sheet?,scroll,swiftui,popover,geometryreader,lazyvgrid,Scroll,Swiftui,Popover,Geometryreader,Lazyvgrid,这是我的例子,我不知道这是否是一个bug。我的所有单元格都正确加载,但当我尝试将DetailView()作为一张工作表显示时,输入的项目始终是网格中首先显示的项目(在我的示例中是左上角),而不是点击的“单元格”。那么,为什么ForEach循环中的项正确地填充了单元格,但没有通过按钮传递到.sheet import SwiftUI let columnCount: Int = 11 let gridSpacing: CGFloat = 1 struct Grid

这是我的例子,我不知道这是否是一个bug。我的所有单元格都正确加载,但当我尝试将
DetailView()
作为一张工作表显示时,输入的项目始终是网格中首先显示的项目(在我的示例中是左上角),而不是点击的“单元格”。那么,为什么ForEach循环中的项正确地填充了单元格,但没有通过按钮传递到.sheet

    import SwiftUI

    let columnCount: Int = 11
    let gridSpacing: CGFloat = 1

    struct GridView: View {
        
        @State var showingDetail = false
        
        let data = (1...755).map { "\($0)" }
        let columns: [GridItem] = Array(repeating: .init(.flexible(), spacing: gridSpacing), count: columnCount)
        let colCount: CGFloat = CGFloat(columnCount)
        var body: some View {
            GeometryReader { geo in
                ScrollView (showsIndicators: false) {
                    LazyVGrid(columns: columns, spacing: gridSpacing) {
                        ForEach(data, id: \.self) { item in
                            
                            Button(action: {
                                self.showingDetail.toggle()
                            }) {
                                GridCell(item: item, size: (geo.size.width - (colCount * gridSpacing)) / colCount)
                            }.sheet(isPresented: $showingDetail) {
                                DetailView(item: item)
                            }
                        }
                    }
                }
                .padding(.horizontal, gridSpacing)
            }
        }
    }

    struct GridCell: View {
        let isVault: Bool = false
        let item: String
        let size: CGFloat
        var body: some View {
            ZStack {
                Rectangle()
                    .fill(Color.orange)
                    .cornerRadius(4)
                Text(item)
                    .foregroundColor(.white)
                    .font(.system(size: size * 0.55))
            }
            .frame(height: size)
        }
    }

    struct DetailView: View {
        
        let item: String
        
        var body: some View {
            Text(item)
        }
    }

    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            GridView()
                .preferredColorScheme(.dark)
        }
    }


我错过了什么?另外,在我的iPad pro 11上滚动有点神经质,有人看到过同样的行为吗?

在这种情况下,更适合使用由项构造的工作表变体,因为工作表必须从动态内容中移出(否则,您在ForEach中创建的工作表数量与项目数量相同)

这是可能的解决办法。使用Xcode 12/iOS 14进行测试

// helper extension because .sheet(item:...) requires item to be Identifiable
extension String: Identifiable {
    public var id: String { self }
}

struct GridView: View {

    @State private var selected: String? = nil

    let data = (1...755).map { "\($0)" }
    let columns: [GridItem] = Array(repeating: .init(.flexible(), spacing: gridSpacing), count: columnCount)
    let colCount: CGFloat = CGFloat(columnCount)
    var body: some View {
        GeometryReader { geo in
            ScrollView (showsIndicators: false) {
                LazyVGrid(columns: columns, spacing: gridSpacing) {
                    ForEach(data, id: \.self) { item in

                        Button(action: {
                            selected = item      // store selected item
                        }) {
                            GridCell(item: item, size: (geo.size.width - (colCount * gridSpacing)) / colCount)
                        }
                    }
                }
            }.sheet(item: $selected) { item in     // activated on selected item
                DetailView(item: item)
            }
            .padding(.horizontal, gridSpacing)
        }
    }
}

在这种用例中,更适合使用使用项构造的工作表变体,因为工作表必须从动态内容中移出(否则您创建的工作表数量与ForEach中的项目数量相同)

这是可能的解决办法。使用Xcode 12/iOS 14进行测试

// helper extension because .sheet(item:...) requires item to be Identifiable
extension String: Identifiable {
    public var id: String { self }
}

struct GridView: View {

    @State private var selected: String? = nil

    let data = (1...755).map { "\($0)" }
    let columns: [GridItem] = Array(repeating: .init(.flexible(), spacing: gridSpacing), count: columnCount)
    let colCount: CGFloat = CGFloat(columnCount)
    var body: some View {
        GeometryReader { geo in
            ScrollView (showsIndicators: false) {
                LazyVGrid(columns: columns, spacing: gridSpacing) {
                    ForEach(data, id: \.self) { item in

                        Button(action: {
                            selected = item      // store selected item
                        }) {
                            GridCell(item: item, size: (geo.size.width - (colCount * gridSpacing)) / colCount)
                        }
                    }
                }
            }.sheet(item: $selected) { item in     // activated on selected item
                DetailView(item: item)
            }
            .padding(.horizontal, gridSpacing)
        }
    }
}