在 Swift 中将自定义网格视图格式化为定期 Table?

Formatting Custom Grid View to Periodic Table in Swift?

如何重新格式化视图主体中的 GridStack 代码,以便我可以每行复制它,例如 1 行 2 列、2 行 8 列、4 行 18 列、2 行 15 列?,我正在用这个假设切出洞来塑造一个交互式周期Table,参考附图。

@jnpdx 提供了每个单元格坐标显示功能的示例,除此之外,我还需要一个 ontapgesture 来操作每个单元格的数据叠加,以便我可以将信息发送到其他菜单字段。

@jnpdx 所以现在就在这个编辑中的圆角矩形之前打开注释掉的显示功能,我需要一些如何在每个单元格上放置自定义数据而不是每个单元格上的氢加上创建一个 ontapgesture 以发送全球到应用程序中的其他菜单字段?

struct GridStack<Content: View>: View {
   
    let rows: Int
    let columns: Int
    let content: (Int, Int) -> Content
    
    

    //func shouldDisplayAtCoord(row: Int, column: Int) { if row == 0 && column > 1 { return true } }
    
    var body: some View {
        VStack {
                    ForEach(0 ..< rows, id: \.self) { row in
                       
                        HStack {
                            ForEach(0 ..< columns, id: \.self) { column in
                                ZStack{
                                RoundedRectangle(cornerRadius: 5)
                                            .fill(Color.brown)
                                            .frame(width: 40, height: 50)
                            Image("RadicalDeepscale30").opacity(0.4)
                            content(row, column)
                              
                                 
                            }
                            }
                        }
                    }
                }
       
    }
    init(rows: Int, columns: Int, @ViewBuilder content: @escaping (Int, Int) -> Content) {
        self.rows = rows
        self.columns = columns
        self.content = content
    }
}

// An example view putting GridStack into practice.
struct DETEView: View {
    var body: some View {
        
        VStack(alignment: .center) {
            Text("DART Edge Table of Elements")
                .font(.largeTitle)
                .bold()
                //.colorInvert()
                .padding(.top, 20)
                .shadow(radius: 3)
        }
        
            VStack(alignment: .center) {
                HStack(alignment: .center){
                    VStack(alignment: .center) {
        GridStack(rows: 9, columns: 18) { row, col in
            VStack(alignment: .leading){
                HStack(alignment: .top) {
            VStack(alignment: .leading) {
            Text("1")
                .font(.system(size: 9))
               // .bold()
                //.shadow(radius: 1)
            }
                }
                HStack(alignment: .center) {
                VStack(alignment: .center){
                    Text("H")
                        .font(.system(size: 12))
                        .bold()
                        //.shadow(radius: 1)
            Text("Hydrogen")
                .font(.system(size: 7))
                //.bold()
               // .shadow(radius: 1)
                //.padding(.top, 1)
                }
                }
            }
        }
                    }
                }

            }.frame(width: 950, height: 670, alignment: .top).padding(.top, 20)
    }
        }

      

这是一个简单的实现,使用了与我们在 comments/chat 中讨论的策略类似的策略。在这种情况下,它不是使用函数来确定是否应显示元素,而是在列出元素的 table 中查找并根据它们在网格上的坐标存储它们。

struct GridStack<Content: View>: View {
    
    let rows: Int
    let columns: Int
    let content: (Int, Int) -> Content
    
    var body: some View {
        VStack {
            ForEach(0 ..< rows, id: \.self) { row in
                HStack {
                    ForEach(0 ..< columns, id: \.self) { column in
                        content(row,column)
                    }
                }
            }
        }
    }
}

struct ElementCoordinate: Hashable {
    var row : Int
    var column: Int
}

struct Element {
    var atomicNumber: Int
    var name : String
}

let tableOfElements : [ElementCoordinate:Element] = [
    ElementCoordinate(row: 1, column: 1):Element(atomicNumber: 1, name: "Hydrogen"),
    ElementCoordinate(row: 1, column: 18):Element(atomicNumber: 2, name: "Helium"),
    ElementCoordinate(row: 2, column: 1):Element(atomicNumber: 3, name: "Lithium"),
    ElementCoordinate(row: 2, column: 2):Element(atomicNumber: 4, name: "Beryllium"),
    ElementCoordinate(row: 2, column: 13):Element(atomicNumber: 5, name: "Boron"),
    ElementCoordinate(row: 2, column: 14):Element(atomicNumber: 6, name: "Carbon"),
]

struct ContentView: View {
    var body: some View {
        GridStack(rows: 9, columns: 18) { row, column in
            ZStack{
                if let element = tableOfElements[ElementCoordinate(row: row + 1, column: column + 1)] {
                    RoundedRectangle(cornerRadius: 5)
                        .fill(Color.brown)
                    Image("RadicalDeepscale30").opacity(0.4)
                    Text(element.name)
                }
            }
            .frame(width: 40, height: 50)
        }
    }
}

查询网格时注意行号和列号上的+ 1,因为rowcolumn在Swift代码中是从零开始的,但是我的tableOfElements1 的索引开始。

这不仅会向您展示如何进行布局,还会向您展示如何将每个坐标与特定元素相关联。

显然,实施细节可能会发生变化以适应您自己的模型,但这应该让您了解如何开始。