2

UPDATE 14/06

I have come up with a hacked way of getting the result I want, but it is not ideal.

Using the following extension (from https://www.hackingwithswift.com/example-code/language/how-to-split-an-array-into-chunks) I can chunk my array of items into e.g. pairs:

extension Array {
    func chunked(into size: Int) -> [[Element]] {
        return stride(from: 0, to: count, by: size).map {
            Array(self[$0 ..< Swift.min($0 + size, count)])
        }
    }
}

I can then create an array of arrays split into the specified chunk size, and wrap a load oh HStacks in a VStack as like this:

var body: some View {
    
    VStack {
        ForEach(itemText.chunked(into: 2), id: \.self) { textCouple in
            HStack {
                ForEach(textCouple, id: \.self) { text in
                   item(text: text)
                        .frame(width: 150)
                }
            }
        }
        .fixedSize(horizontal: false, vertical: true)
    }
}

Like I say, I'd still like to find a solution with LazyVGrid is this hacked solution does not seem very extendable but at least it's something!

From iOS14 it appears that views within a LazyVGrid row no longer expand to fill available space.

My scenario

I have an array of views which all contain (among other things) text content which is individual to that view and can expand over multiple lines. What I need is for each row in my VGrid to be set to the height of the largest item in that row, and for the other item(s) to expand so that they are the same height as the largest item in the row.

So here is a very crude take on my project code:

struct SwiftUIView: View {
    let resultGridLayout = [GridItem(.adaptive(minimum: 160), spacing: 10, alignment: .top)]
    
    let itemText = [
        "Test 1",
        "Testung 122kdjaslkdjakldjklasdmasd",
        "Teslksjf",
        "Telksj;flkjasf;lkjasflkja;slfkjas;lkfjaslkfjaskfjas;kfj;askfj;askfj;aslkfj;askfj;aslkfj;asklfj",
        "Test3",
        "`kjdnlaskdnaskljndjkasndkjasndajksndla"
        
    ]
    
    var body: some View {
        LazyVGrid(columns: resultGridLayout, spacing: 10) {
            
            ForEach(itemText, id: \.self) { text in
                item(text: text)
                    .frame(maxHeight: .infinity)
            }
        }
    }
    
    func item(text: String) -> some View {
        Text(text)
            .padding()
            .background(Color.blue.opacity(0.3))
            .cornerRadius(10)
    }
}

And the result:

enter image description here

So as we can see, the views containing less text do not expand to fill the space. So the effect I'm looking to achieve would be something along these lines where each row can be a different height to the last depending on the height of the tallest view, but each item in each row is of consistent height:

enter image description here

I cannot resize to the largest item in the entire grid, as there will be many, many items and I do not want a scenario whereby just one of them is much taller than the others and I end up unnecessarily resizing every item in the grid.

DevB1
  • 1,235
  • 3
  • 17
  • 43

0 Answers0