Shawkath Srijon
Shawkath Srijon

Reputation: 929

SwiftUI: How to put a line break within ForEach loop where it repeats a view in it

I have a dynamic SwiftUI view where I pass information through parameter. After, I try to make copies of the view using ForEach loop. The views appear as usual vertically in a Stack. However, I would like to present the all views in three different lines. Could anyone please present a efficient solution?

I want this design:

And I want this:

But I have got this:

I have got this:

My code:

struct AllDaysView: View {
    @Binding var hasMenuShown: Bool
    var days: [String] = NextDaysView().days

    var body: some View {
        VStack {
            MenuBarView(hasMenuShown: $hasMenuShown)
            ForecastButtonsView()
            HStack {
                ForEach(days, id: \.self) { day in
                    SingleDaySummaryView(day: day)
                }
            }
            Spacer()
        }
    }
}

Upvotes: 2

Views: 3715

Answers (1)

cbjeukendrup
cbjeukendrup

Reputation: 3446

First, let's make a way to divide the array in groups of three.

extension Array {
    func dividedIntoGroups(of i: Int = 3) -> [[Element]] {
        var copy = self
        var res = [[Element]]()
        while copy.count > i {
            res.append( (0 ..< i).map { _ in copy.remove(at: 0) } )
        }
        res.append(copy)
        return res
    }
}

Change the days var:

var days: [String] = NextDaysView().days.dividedIntoGroups(of: 3)

Now, let's make the new code for body:

VStack {
    MenuBarView(hasMenuShown: $hasMenuShown)
    ForecastButtonsView()
    ForEach(days, id: \.self) { dayRow in
        HStack {
            ForEach(dayRow, id: \.self) { day in
                SingleDaySummaryView(day: day)
            }
        }
    }
    Spacer()
}

In this code, you can easily change the number of views per row, but it seems quite difficult to make it really dynamic. When you want to do that, you could use GeometryReader to get the screen width, but to calculate the number of views per row, you will of course also need the width of one view, and that's tricky. This article may contain information that could lead to a solution: https://swiftui-lab.com/communicating-with-the-view-tree-part-1/

I couldn't really test this code, because I'm not working on my Mac right now, but hopefully it works or will at least help you!

Upvotes: 2

Related Questions