使用 ForEach 循环 SwiftUI 绘制矩形

Drawing Rectangles using a ForEach loop SwiftUI

我正在尝试创建一个矩形视图,其中包含给定数量的矩形,

即Image

我正在尝试通过传入尺寸的选项重新创建它以向其添加更多级别,目前我只设法覆盖

        let colors: [Color] = [.red, .green, .blue]

        var body: some View {

            ZStack {
                ForEach(colors, id: \.self) { color in
                    Text(color.description.capitalized)
                        .background(color)
                }
            }
        }

这是我在寻找问题时才发现的,我唯一的问题是具有可调整的大小值,在使用循环时可以逐渐变小,目前我得到的最接近的是:

struct SquareContent{
    var color: Color
    var size: CGSize
}

struct GrannySquareComplete: View {
    let colors: [SquareContent] = [
        SquareContent.init(color: .red, size: CGSize(width: 100, height: 100)),
        SquareContent.init(color: .white, size: CGSize(width: 80, height: 80)),
        SquareContent.init(color: .red, size: CGSize(width: 80, height: 80))]
    
    var body: some View {
        ZStack {
            ForEach(0...colors.count) { i in
                Text("")
                    .frame(width: colors[i].size.width, height: colors[i].size.height)
                    .background(colors[i].color)
                    .border(.white)
            }
        }
    }
}

但这returns是

的一个错误

No exact matches in call to initialiser

我认为这是由于在 foreach 循环中使用了文本,但不知道如何解决这个问题。

要修复您的错误,请将 ForEach(0...colors.count) { i in 更改为

ForEach(0..<colors.count) { i in

使其动态化

//Make Identifiable
struct SquareContent: Identifiable{
    //Add id
    let id: UUID = UUID()
    var color: Color
    //Handle size based on screen
}

struct GrannySquareComplete: View {
    //Change to @State
    @State var colors: [SquareContent] = [
        SquareContent.init(color: .red),
        SquareContent.init(color: .white),
        SquareContent.init(color: .red)]
    
    var body: some View {
        VStack{
            //Mimic adding a square
            Button("add square"){
                colors.append(.init(color: [.blue, .black,.gray, .orange, .pink].randomElement()!))
            }
        ZStack(alignment: .center){
            ForEach(Array(colors.enumerated()), id: \.offset) { (index, color) in
                //Calculate the size by percentange based on index
                let percentage: CGFloat = Double(colors.count - index)/Double(colors.count)
                //Create a custom view to handle the details
                SquareComplete(square: color, percentage: percentage)
            }
        }
        }
    }
}
struct SquareComplete: View {
    let square: SquareContent
    let percentage: CGFloat
    var body: some View{
        GeometryReader{ geo in
            Rectangle()
                //Make a square
                .aspectRatio(1, contentMode: .fit)
                .border(.white)
                .background(square.color)
                .foregroundColor(.clear)
                //Center
                .position(x: geo.size.width/2, y: geo.size.height/2)
                //Adjust size by using the available space and the passed percentage
                .frame(width: geo.size.width * percentage, height: geo.size.height * percentage, alignment: .center)
        }
    }
}

struct GrannySquareComplete_Previews: PreviewProvider {
    static var previews: some View {
        GrannySquareComplete()
    }
}