Reputation: 531
In my SwiftUI app, I have a List
inside of a sidebar NavigationView
with 2 rows, like this:
List {
NavigationLink(destination: MyView1()) {
Label("Test Row 1", systemImage: "list.bullet")
}
NavigationLink(destination: MyView2()) {
Label("Test Row 2", systemImage: "shippingbox")
.frame(maxWidth: .infinity, alignment: .leading)
}
}
However the second row is taller that the first row, I believe due to the image. If I change the image to this:
NavigationLink(destination: MyView2()) {
Label("Test Row 2", systemImage: "list.number")
.frame(maxWidth: .infinity, alignment: .leading)
}
the rows are now the same height. I don't want to fix the height of the rows, but I was wondering if there was a solution where the rows could be the same height.
Upvotes: 0
Views: 855
Reputation: 9695
If you want to ensure that the rows are even, you can use PreferenceKeys
to set the row heights to the height of the tallest row like this:
struct EvenHeightListRow: View {
@State var rowHeight = CGFloat.zero
var body: some View {
List {
NavigationLink(destination: Text("MyView1")) {
Label("Test Row 1)", systemImage: "list.bullet")
// This reads the height of the row
.background(GeometryReader { geometry in
Color.clear.preference(
key: HeightPreferenceKey.self,
value: geometry.size.height
)
})
.frame(height: rowHeight)
}
NavigationLink(destination: Text("MyView2")) {
Label("Test Row 2)", systemImage: "shippingbox")
.background(GeometryReader { geometry in
Color.clear.preference(
key: HeightPreferenceKey.self,
value: geometry.size.height
)
})
.frame(height: rowHeight)
.frame(maxWidth: .infinity, alignment: .leading)
}
}
// this sets backgroundSize to be the max value of the tallest row
.onPreferenceChange(HeightPreferenceKey.self) {
rowHeight = max($0, rowHeight)
}
}
}
// This is the actual preferenceKey that makes it work.
fileprivate struct HeightPreferenceKey: PreferenceKey {
static var defaultValue: CGFloat = .zero
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {}
}
Upvotes: 1