I’m trying to achieve a specific UI design in SwiftUI where the bottom section of my List has a different background color than the top section. For example, the "Your Medications" Section has a different background than the top "Log" Section:
Goal layout:
Here some example code. I wonder if I am supposed to use two Lists instead. If I use two Lists though and nest it in a ScrollView
, the height of the lists needs to be specified. I am working with dynamic content, though so I don’t think that is ideal.
class ProtocolMedication {} // Example model
struct HomeView: View {
@Query private var protocolMedications: [ProtocolMedication]
var body: some View {
NavigationStack {
List {
// Upper sections with default background
Section {
Text("Content 1")
} header: {
Text("Log")
}
// Bottom section that needs different background
Section {
ForEach(protocolMedications) { medication in
Text(medication.name)
}
} header: {
Text("Your Medications")
}
}
.listStyle(.insetGrouped)
}
}
}
2
Answers
You could use
.listRowBackground()
:If I understand correctly, you want a different color for the outer background around the section, this being the list group background.
The default background can be hidden by applying
.scrollContentBackground(.hidden)
to theList
. Then you can apply your own.background
to theList
.The default background is
UIColor.systemGroupedBackground
, so this can be used as the first layer in aZStack
that you show in the background.Show the color for the section background as the next layer in the
ZStack
.The position of the second color can be matched to the section header using
.matchedGeometryEffect
withalignment: .top
.Apply
.frame(maxWidth: .infinity, alignment: .leading)
to the content of the section header, so that.top
(used for matching position) is then the middle of the row, not just the middle of the content.Padding can be used to tweak the position, if necessary.
If you had more sections then you can use the same technique for them too. Each section would have its own layer in the
ZStack
. In this case, you might want to avoid colors that are partially transparent (colors with opacity), unless you want the transparency effects to combine.For the list rows themselves, set your own background using
.listRowBackground
.