vasily
vasily

Reputation: 2920

Table with alternating row colors in SwiftUI

How do I create own control that would work like follows

StripedTable(colors: [Color.blue, Color.red]) {
    HStack { ... }
    Text()
    Whatverer()
}

and it will apply the blue background to HStack and Whatever, and the red background to Text.

Upvotes: 0

Views: 860

Answers (3)

tcobbs
tcobbs

Reputation: 419

I got it to work without having to walk through the indexes using a helper function. Not sure if this is better than Oscar Franco's reply, but like his, it will work with an odd number of elements:

struct Alternating: View {
    var backgroundColors = [
        Color.red,
        Color.blue,
    ]
    var dummyValues = ["One", "Two", "Three", "Four", "Five"]

    func nextBackgroundIndex(_ index: inout Int) -> Int {
        index = index + 1
        return index % 2
    }
    var body: some View {
        var index = 0
        VStack {
            ForEach(dummyValues, id: \.self) { dummyValue in
                Text(dummyValue)
                    .frame(maxWidth: .infinity)
                    .background(backgroundColors[nextBackgroundIndex(&index)])
            }
        }
    }
}

Upvotes: 1

Chris
Chris

Reputation: 8126

check this out:

struct StripedTable<Content, Content2> : View where Content: View, Content2: View {

    var content: Content
    var content2: Content2

    var colors: [Color]

    public init(colors: [Color], @ViewBuilder content: () -> Content, @ViewBuilder content2: () -> Content2) {
        self.colors = colors
        self.content = content()
        self.content2 = content2()
    }
    var body: some View {
        VStack {
            content.background(colors[0])
            content2.background(colors[1])
        }
    }
}


struct ContentView: View {
    var body: some View {
        VStack {
            ForEach(UIFont.familyNames, id: \.self) { index in
                StripedTable(colors: [Color.blue, Color.red], content: {
                    HStack {
                        Text("just")
                        Text("a")
                        Text("test")
                    }
                },content2: {
                    Text("in red")
                })
            }
        }
    }
}

Result:

enter image description here

Upvotes: 1

Oscar Franco
Oscar Franco

Reputation: 6260

I don't think you can do this by manually coding each item in your table, what I did end up doing is something like:

ScrollView {
  ForEach(0..<itemList.count, id: \.self) { idx in
    MyItem(index: idx, item: itemList[idx])
  }
}

and then on your item

var body: some View {
  HStack {
    // Some component code
  }.backgroundColor(index % 2 == 0 ? Color.blue : Color.red)
}

Upvotes: 1

Related Questions