Reputation: 1131
I am trying to implement a sticky footer in a List View in SwiftUI
It doesn't seem to operate the same as the header per say. This is an example of a sticky header implementation
List {
ForEach(0..<10) { index in
Section(header: Text("Hello")) {
ForEach(0..<2) { index2 in
VStack {
Rectangle().frame(height: 600).backgroundColor(Color.blue)
}
}
}.listRowInsets(EdgeInsets())
}
}
This above gives a sticky header situation. Although, once I change Section(header: ...
to Section(footer:...
it doesn't seem to be sticky anymore, it's simply places at the end of the row.
A more explicit reference
List {
ForEach(0..<10) { index in
Section(footer: Text("Hello")) {
ForEach(0..<2) { index2 in
VStack {
Rectangle().frame(height: 600).backgroundColor(Color.blue)
}
}
}.listRowInsets(EdgeInsets())
}
}
Does anyone have any solutions for this?
Upvotes: 9
Views: 11412
Reputation: 4377
Swift 5 / 2023 / iOS 16
List {
...
}
.toolbar {
ToolbarItemGroup(placement: .bottomBar) {
Text("App iOS Version 1.0.0 (xyz)")
.font(.footnote)
.foregroundColor(.secondary)
.frame(maxWidth: .infinity)
.textSelection(.enabled)
}
}
Upvotes: 10
Reputation: 36078
You can use overlay
on the List
:
struct ContentView: View {
@State private var selectedTab = 0
var body: some View {
TabView(selection: $selectedTab) {
VStack {
List {
ForEach(0..<20, id: \.self) { _ in
Section {
Text("Item 1")
Text("Item 2")
Text("Item 3")
}
}
}
.listStyle(InsetGroupedListStyle())
.overlay(
VStack {
Spacer()
Text("Updated at: 5:26 AM")
.font(.footnote)
.foregroundColor(.secondary)
.frame(maxWidth: .infinity)
}
)
}
.tabItem {
Label("First", systemImage: "alarm")
}
Text("Content 2")
.tabItem {
Label("Second", systemImage: "calendar")
}
}
}
}
Upvotes: 1
Reputation: 1131
With the latest on SwiftUI (2) we now have access to a few more API's
For starters we can use a LazyVStack
with a ScrollView
to give us pretty good performance, we can then use the pinnedViews
API to specify in an array which supplementary view we want to pin or make sticky. We can then use the Section view which wraps our content and specify either a footer or header.
** This code is working as of Xcode beta 2 **
As for using this in a List
I'm not too sure, will be interesting to see the performance with List
vs Lazy...
struct ContentView: View {
var body: some View {
ScrollView {
LazyVStack(spacing: 10, pinnedViews: [.sectionFooters]) {
ForEach(0..<20, id: \.self) { index in
Section(footer: FooterView(index: index)) {
ForEach(0..<6) { _ in
Rectangle().fill(Color.red).frame(height: 100).id(UUID())
}
}
}
}
}
}
}
struct FooterView: View {
let index: Int
var body: some View {
VStack {
Text("Footer \(index)").padding(5)
}.background(RoundedRectangle(cornerRadius: 4.0).foregroundColor(.green))
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Upvotes: 6