如何在 SwiftUI 中让 2x2 正方形适合屏幕

How to have 2x2 made of squares fit screen in SwiftUI

我正在尝试通过 VStacks/HStacks 或 LazyVGrid 创建一个 2x2 网格,以使每行上的正方形适合屏幕。例如,第一个和第二个方块各占屏幕宽度的一半,并根据该长度确定高度以使其成为一个正方形。我将如何以我提到的两种方式去做,或者有更好的方法吗?这是我目前所拥有的。

VStack {
    HStack {
        Rectangle()
            .fill(Color.gray)
            .frame(width: 100, height: 100)

        Rectangle()
            .fill(Color.blue)
            .frame(width: 100, height: 100)
    }
    HStack {
        Rectangle()
            .fill(Color.red)
            .frame(width: 100, height: 100)

        Rectangle()
            .fill(Color.green)
            .frame(width: 100, height: 100)
    }
}

在这里硬编码框架的宽度和高度 属性 感觉不对,或者这是消除正方形之间间隙的方法?这种硬编码值的方式是否可以扩展到其他 phone 大小?

LazyVGrid(columns: layout) {
    Rectangle()
        .fill(Color.gray)
        .frame(width: 210, height: 210)
    Rectangle()
        .fill(Color.blue)
        .frame(width: 210, height: 210)
    Rectangle()
        .fill(Color.red)
        .frame(width: 210, height: 210)
    Rectangle()
        .fill(Color.green)
        .frame(width: 210, height: 210)
}

编辑:这是获得我想要的新代码的样子。

VStack(spacing: 0) {
    HStack(spacing: 0) {
        Rectangle()
            .fill(Color.gray)

        Rectangle()
            .fill(Color.blue)

    }
    HStack(spacing: 0) {
        Rectangle()
            .fill(Color.red)

        Rectangle()
            .fill(Color.green)

    }
}
.aspectRatio(1.0, contentMode: .fit)

现在让它与 LazyVGrid 一起工作。

您可以使用 GeometryReader,如 here.

用法示例:

struct MyView: View {
    var body: some View {
       GeometryReader { geo in
           //You now have access to geo.size.width and geo.size.height
       }
    }
}

It feels wrong to hardcode the width and height for frame here or is that the way to go about removing the gaps between the squares?

要消除方块之间的间隙,只需修改 HStack / VStack 以包括间距:

HStack(alignment: .center, spacing: 0, content: {
            Rectangle()
                .fill(Color.gray)
                .frame(width: 100, height: 100)

            Rectangle()
                .fill(Color.blue)
                .frame(width: 100, height: 100)
})

只需应用aspectRatio(值为1且适合屏幕)修饰符,无需指定任何框架。

VStack {
    HStack {
        Rectangle()
            .fill(Color.gray)
            
        Rectangle()
            .fill(Color.blue)
            
    }
    HStack {
        Rectangle()
            .fill(Color.red)
        
        Rectangle()
            .fill(Color.green)
            
    }
}
.aspectRatio(1.0, contentMode: .fit)