Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to vertically merge cells in a SwiftUI Grid

Tags:

swiftui

I am trying to merge cells in a SwiftUI Grid vertically. But I don't see how. Take the example below. How can I merge the two red cells (first cell in the first row and the first cell in the second row).

import SwiftUI

struct ContentView: View {
    var body: some View {
        
        Grid() {
            GridRow {
                Color.red
                Color.green
                    .gridCellColumns(2)
            }
            GridRow {
                Color.red
                Color.blue
                Color.yellow
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

I was looking for a .gridCellRows(2) attribute, but that does not exist.

like image 322
Alex Avatar asked Sep 11 '25 03:09

Alex


2 Answers

The Grid view does not support merging rows, only columns. But it is possible to use a nested Grid inside the GridRow of an outer Grid:

var body: some View {
        Grid() {
            GridRow {
                Color.red
                Grid() {
                    GridRow {
                        Color.green
                            .gridCellColumns(2)
                    }
                    GridRow {
                        Color.blue
                        Color.yellow
                    }
                }
            }
        }
    }

result

This is very hard-coded for your example and would be difficult to generalise to more complex layouts. And it is probably impossible to make it dynamic at run time instead of compile time.

like image 86
Geoff Hackworth Avatar answered Sep 13 '25 06:09

Geoff Hackworth


Little bit hacky... but it does work:

    import SwiftUI

struct ContentView: View {
    var body: some View {
        GeometryReader { screenSize in
            Grid(horizontalSpacing: 0, verticalSpacing: 0) {
                GridRow {
                    ZStack {
                        Color.red
                            .position(CGPoint(x: screenSize.size.width/4, y: screenSize.size.height / 4 * 3))
                            .frame(height: screenSize.size.height)
                    }
                    .frame(height: screenSize.size.height / 2)
                    Color.blue
                }
                GridRow {
                    Color.clear
                    Color.green
                }
            }
        }
    }
}

Basically we exploiting the fact that the view in cell does not have to "fit" inside the cell. The result looks like this:

result layout

like image 35
Andrei Tchijov Avatar answered Sep 13 '25 05:09

Andrei Tchijov