0
0
iOS Swiftmobile~20 mins

Pull-to-refresh (refreshable) in iOS Swift - Mini App: Build & Ship

Choose your learning style9 modes available
Build: Refreshable List
A screen that shows a list of items and allows the user to pull down to refresh the list content.
Target UI
---------------------
| Refreshable List  |
---------------------
| * Item 1          |
| * Item 2          |
| * Item 3          |
| * Item 4          |
| * Item 5          |
---------------------
(Pull down to refresh)
Display a vertical list of 5 items labeled 'Item 1' to 'Item 5'.
Add pull-to-refresh functionality using SwiftUI's refreshable modifier.
When pulled, simulate a 2-second refresh delay and then update the list by appending a new item labeled 'New Item X'.
Show a loading spinner during refresh.
Starter Code
iOS Swift
import SwiftUI

struct RefreshableListView: View {
    @State private var items = ["Item 1", "Item 2", "Item 3", "Item 4", "Item 5"]

    var body: some View {
        NavigationView {
            List {
                ForEach(items, id: \.self) { item in
                    Text(item)
                }
            }
            .navigationTitle("Refreshable List")
            // TODO: Add pull-to-refresh here
        }
    }
}

struct RefreshableListView_Previews: PreviewProvider {
    static var previews: some View {
        RefreshableListView()
    }
}
Task 1
Task 2
Task 3
Solution
iOS Swift
import SwiftUI

struct RefreshableListView: View {
    @State private var items = ["Item 1", "Item 2", "Item 3", "Item 4", "Item 5"]

    var body: some View {
        NavigationView {
            List {
                ForEach(items, id: \.self) { item in
                    Text(item)
                }
            }
            .navigationTitle("Refreshable List")
            .refreshable {
                try? await Task.sleep(nanoseconds: 2_000_000_000) // 2 seconds delay
                let newItemNumber = items.count + 1
                items.append("New Item \(newItemNumber)")
            }
        }
    }
}

struct RefreshableListView_Previews: PreviewProvider {
    static var previews: some View {
        RefreshableListView()
    }
}

This solution uses SwiftUI's .refreshable modifier to add pull-to-refresh functionality to the List. When the user pulls down, the refresh closure runs asynchronously.

Inside the closure, Task.sleep pauses for 2 seconds to simulate loading. Then, a new item labeled "New Item X" is appended to the items array, where X is the next number after the current count.

The list automatically updates because items is a @State variable. The loading spinner is shown automatically by SwiftUI during the refresh.

Final Result
Completed Screen
---------------------
| Refreshable List  |
---------------------
| * Item 1          |
| * Item 2          |
| * Item 3          |
| * Item 4          |
| * Item 5          |
---------------------
(Pull down to refresh)

After refresh:
---------------------
| Refreshable List  |
---------------------
| * Item 1          |
| * Item 2          |
| * Item 3          |
| * Item 4          |
| * Item 5          |
| * New Item 6      |
---------------------
User pulls down on the list to trigger refresh.
A spinner appears at the top indicating loading.
After 2 seconds, the spinner disappears and a new item labeled 'New Item 6' is added to the bottom of the list.
Each subsequent pull adds another new item with incremented number.
Stretch Goal
Add a button in the navigation bar that resets the list to the original 5 items.
💡 Hint
Use a toolbar item with a Button that sets the items array back to the initial list.