Create an Infinitely Scrolling List in SwiftUI
Written by Team Kodeco
Creating an infinitely scrolling list in SwiftUI can help provide a seamless and fluid user experience, especially when dealing with large sets of data. It’s often used in applications that load content dynamically from a server as the user scrolls.
Here’s how you might set up a simple infinitely scrolling list in SwiftUI:
struct ContentView: View {
@State private var numbers: [Int] = Array(1...20)
@State private var isLoading = false
@State private var isFinished = false
var body: some View {
NavigationStack {
List {
ForEach(numbers, id: \.self) { number in
Text("Row \(number)")
}
if !isFinished {
ProgressView()
.frame(maxWidth: .infinity, maxHeight: .infinity)
.foregroundColor(.black)
.foregroundColor(.red)
.onAppear {
loadMoreContent()
}
}
}
.navigationTitle("Infinite List")
}
}
func loadMoreContent() {
if !isLoading {
isLoading = true
// This simulates an asynchronus call
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
let moreNumbers = numbers.count + 1...numbers.count + 20
numbers.append(contentsOf: moreNumbers)
isLoading = false
if numbers.count > 250 {
isFinished = true
}
}
}
}
}
Here’s what your preview should look like:
Try scrolling to the bottom, how many numbers does your list show?
In this example, you first create an array of numbers that you use to populate your list. You also include a Boolean isLoading
state variable that you’ll use to control when you’re currently loading more content.
Inside your List
view, you use the ForEach
loop to generate the list items. You also include a conditional view that will display a ProgressView
(a spinning indicator) when the isFinished
state variable is false
. Imagine we had a server responding with data. isFinished
would become true when the server has no more data to send us.
The onAppear
modifier on the ProgressView
view triggers the loadMoreContent()
function when the view first appears on the screen. onAppear
is on the ProgressView
because we only want to load more data when the user is scrolling down and expects to see more. Imagine trying to load all the data at once!
Inside loadMoreContent
, we simulate an asynchronous loading operation. If we’re not currently loading more content (indicated by isLoading
being false), we set isLoading
to true and then dispatch a delayed task. After the delay, we append more numbers to our array and set isLoading
back to false. This simulates fetching more data from a server. We then check to see if numbers
has more than 100 entries. If so, we set isFinished
to true. This simulates the end of the list and signals there is no more data to fetch.
With this implementation, you can create a simple yet infinitely scrolling list in SwiftUI. This can greatly enhance the user experience, especially when dealing with large data sets. Try it out in your app today!