Reputation: 547
I'm novice in SwiftUI and still can't understand how to make sticky bar on the top of the List
. Like letters in apple music app when you listing artists or songs (look example).
I explored abilities of the List
and NavigationView
, but got nothing. 😔
Upvotes: 11
Views: 17943
Reputation: 389
SwiftUI How to make sticky Header View or header stay on the top of each Section/cell in List.
Steps:
1- Add Scroll View
2- Use forEach in scroll view
3- Use LazyVStack inside forEach and add pinnedView as section header in LazyVStack
4- Inside LazyVStack use Section with header
Sample Code:
@State var headerTitleArray = ["28 Jun, 15:00","29 July, 15:00","30 Aug, 15:00","31 Sep, 15:00","1 Oct, 15:00"]
For Example we have this array of header titles in it.
ScrollView {
ForEach(0..<headerTitleArray.count, id: \.self) { listIndex in
LazyVStack(alignment: .leading, spacing: 0, pinnedViews: [.sectionHeaders]) {
Section {
ForEach(0..<10, id: \.self) { landmark in
//MARK: - Items in per section
Text("section items")
}
} header: {
//MARK: - Seaction header title
Text("\(headerTitleArray(listIndex))")
.font(AppFont(size: 18,type: "Medium"))
.foregroundColor(AppColors.labelColor)
.padding(.vertical,12)
.padding(.horizontal,16)
}
}
}//foreach } //scrollView
Upvotes: 2
Reputation:
This is easier way to use Sticky Header try this approach and let me know is it working...
struct LatestMagazineView: View {
@Environment(\.dismiss) var dismiss
let columns = [GridItem(.flexible()),GridItem(.flexible())]
@State var searchText: String = ""
var body: some View {
ZStack {
VStack(spacing:0) {
Color.orange.ignoresSafeArea().frame(height: 25)
ScrollView{
VStack(spacing: 0){
AsyncImage(url: URL(string: "")){img in
img.resizable().frame(height: 225)
}placeholder: {
Image("Anoop").resizable().frame(height: 225)
}
Image("soft").resizable().frame(width: UIScreen.main.bounds.width, height: 65, alignment: .leading)
LazyVGrid(columns: columns, spacing: 10, pinnedViews: [.sectionHeaders]){
Section(header:
VStack{
TextField("Enter Search Text...", text: $searchText).font(.title)
.padding(4)
.padding(.leading,searchText.isEmpty ? 29 : 4)
.foregroundColor(.white)
.cornerRadius(8)
.overlay(
RoundedRectangle(cornerRadius: 22)
.stroke(Color.white, lineWidth: 2)
)}.padding(6).background(Color.yellow)
) {
ForEach(0..<21){_ in
VStack(alignment: .leading){
AsyncImage(url: URL(string: "")){ img in
img .resizable()
.frame(height: 255)
}placeholder: {
Image("soft")
.resizable()
.frame(height: 255)
}
}.padding(8).background(Color.white).cornerRadius(4).shadow(radius: 1)
}
}
}
}
}
}
}
}
}
Upvotes: 0
Reputation: 109
LazyVStack
provides an initializer with a pinnedView
parameter that does exactly this.
Upvotes: 10
Reputation: 201
You can use List style .listStyle(PlainListStyle())
on List and use Section
on iOS 13 +
for Example
struct ContentView: View {
var content = MyData()
var body: some View {
List {
ForEach(content.sections, id: \.title) { section in
Section(content: {
ForEach(section.rows, id: \.self) { row in
Text(row)
}
}, header: {
Text(section.title)
})
}
}
.listStyle(PlainListStyle())
}
}
Given:
struct MyData {
struct Section {
var title: String
var rows: [String]
}
var sections: [Section] = []
}
Upvotes: 4
Reputation: 3386
Use pinnedViews
in the LazyVStack
initializer.
LazyVStack(pinnedViews: [.sectionHeaders]) {
Section(header: Text("Sticky Header")) {
ForEach(0...3) { item in
Text(item)
}
}
}
Upvotes: 12
Reputation: 3232
SwiftUI’s
list view has built-in support for sections and section headers, just like UITableView
in UIKit
. To add a section around some cells, start by placing a Section
around it.
What we want to do is create a list view that has two sections: one for important tasks and one for less important tasks. Here’s how that looks:
struct ContentView: View {
var body: some View {
List {
Section(header: Text("Important tasks")) {
TaskRow()
TaskRow()
TaskRow()
}
Section(header: Text("Other tasks")) {
TaskRow()
TaskRow()
TaskRow()
}
}
}
}
Upvotes: 7