如何正确地将“单元格项目”从 SwiftUI LazyVGrid 传递给 .sheet?

Posted

技术标签:

【中文标题】如何正确地将“单元格项目”从 SwiftUI LazyVGrid 传递给 .sheet?【英文标题】:How do I correctly pass a "cell item" to a .sheet from a SwiftUI LazyVGrid? 【发布时间】:2020-08-02 14:37:13 【问题描述】:

这是我的例子,我不知道这是否是一个错误。我的所有单元格都正确加载,但是当我尝试将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 上滚动有点跳动,有没有人看到同样的行为?

【问题讨论】:

【参考方案1】:

在这种用例中,使用由项目构造的工作表变体更合适,因为工作表必须从动态内容中移出(否则您创建的工作表与 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)
        
    

【讨论】:

以上是关于如何正确地将“单元格项目”从 SwiftUI LazyVGrid 传递给 .sheet?的主要内容,如果未能解决你的问题,请参考以下文章

如何正确地将 RealmDB 结果对象映射到 SwiftUI 列表?

如何正确地将 ImagePicker 插入标题中的图像? SwiftUI

SwiftUI TextField 数字输入

如何正确地将日期时间从 c# 传递到 sql?

如何正确地将 blob 从前端传递到后端?

iOS SwiftUI:使用 ScrollView 和 ZStack 正确堆叠 NavigationView?