Search code examples
swiftuiconditional-statementshstack

How to display HStack element based on a conditional in SwiftUI?


How do I test a condition within an HStack to determine how it should be displayed? The following code draws a 3x3 grid made from HStack of HStack.

var body: some View {
    ForEach(0..<3) { v in
        Spacer()
        HStack(spacing: 0) {
            ForEach(0..<3) { h in
                Spacer()
                HStack(spacing: 0) {
                    let x = v * 3 + h
                    Text("\(x)").font(.largeTitle)
                }
                .frame(maxWidth: .infinity, maxHeight: .infinity)
                .background(.yellow)
                Spacer()
            }
        }
        Spacer()
    }
}

enter image description here

How can I do something like:

if x % 2 == 0 { // if even number
    .background(.yellow)
} else {
    .background(.blue)
}

Where do I even stick such a code within the HStack (or any other SwiftUI object)'s declarative statements?


Solution

  • The ternary operator is recommended in this case, ? represents if and : represents else

    var body: some View {
        VStack {
            ForEach(0..<3) { v in
                Spacer()
                HStack(spacing: 0) {
                    ForEach(0..<3) { h in
                        Spacer()
                        let x = v * 3 + h
                        Text("\(x)").font(.largeTitle)
                            .frame(maxWidth: .infinity, maxHeight: .infinity)
                            .background(x % 2 == 0 ? .yellow : .blue)
                        Spacer()
                    }
                }
                Spacer()
            }
        }
    }
    

    The inner HStack is redundant and you need an enclosing VStack.

    Or without the Spacers

    var body: some View {
        VStack(spacing: 10) {
            ForEach(0..<3) { v in
                HStack(spacing: 10) {
                    ForEach(0..<3) { h in
                        let x = v * 3 + h
                        Text("\(x)").font(.largeTitle)
                            .frame(maxWidth: .infinity, maxHeight: .infinity)
                            .background(x % 2 == 0 ? .yellow : .blue)
                    }
                }
            }
        }
        .padding(8)
    }