Paweł Zgoda-Ferchmin
Paweł Zgoda-Ferchmin

Reputation: 469

SwiftUI Make a list that shows only a certain amount of rows

I have recently started messing around with SwiftUI and so far it is great. I have however ecnountered a problem that I can't seem to find an answer to.

I am trying to create this design:

What I want to create

As you can see here is a tableview (a list) which rows have a smaller tableview (a list) inside them. The task was pretty simple while using IB, but with swiftUI I can't seem to find a way to limit the number of rows to only the amount I need or to manually set the lists height based on the number of rows (keep in mind those rows can also be variable in height).

My code so far only consist of creating the List and adding 2 test rows:

List {
    OrderItemRow()
    OrderItemRow()
}

But as you can see SwiftUI automatically stretches the List to fill all the available space. The effect: enter image description here

Upvotes: 3

Views: 4661

Answers (2)

LotU
LotU

Reputation: 46

If you know the height of your rows, this can be achieved like this:

List(self.arrayOfAllItemsInOrder(currentOrder)) { item in
    OrderItemRow(currentOrder: order, item:item)
}
.environment(\.defaultMinListRowHeight, rowHeight)
.frame(height: self.arrayOfAllItemsInOrder.reduce(0) { i, _ in i + rowHeight })

This will calculate the full size of the list based on rowHeight and limit the frame's height.

Note that if the size of your row goes beyond rowHeight, the entire calculation will be messed up and you will probably be seeing half (or missing entire) cells.

Upvotes: 3

Chuck H
Chuck H

Reputation: 8276

I would suggest a List using a ForEach to show your orders and a nested ForEach to show items in an order. The key is to manage the Data being supplied to each ForEach to the number of items desired and also to construct appropriate Row Views for OrderHeaderRow, OrderItemRow, etc.

struct OrdersView: View {
    var body: some View {
        List {
            Section(header: Text("Current Order")) {
                OrderHeaderRow(order: currentOrder)
                ForEach(self.arrayOfAllItemsInOrder(currentOrder)) { item in
                    OrderItemRow(currentOrder: order, item:item)
                }
                OrderTotalRow(order: order)
                ActionButtonsRow(order:order)
            }
            Section(header: Text("Previous Orders")) {
                ForEach(self.arrayOfAllPreviousOrders) { order in
                    OrderHeaderRow(order: order)
                    ForEach(self.arrayOfAllItemsInOrder(order)) { item in
                        OrderItemRow(order: order, item:item)
                    }
                    OrderTotalRow(order: order)
                    ActionButtonsRow(order:order)
                }
            }
        }
    }
}

Upvotes: 1

Related Questions