
前一篇第 13 天是提到「EnvironmentObject」,雖然本系列文章基本上沒有前後關聯,如果你是還沒讀過前一篇的讀者,也推薦你去讀讀。
從 iOS 15 開始, Apple 的 SwiftUI 開始提供 refreshable 這個 modifier ,大家念念在望的功能終於可以用 SwiftUI 的方式實作了。
先來看今天最後要做出來的畫面。

下拉之後可以在清單的前面加上 3 行,並有重置按鈕可以重置回初始狀態。
非常簡單,只要加上這個 modifier 即可!也沒有像 UIKit 需要較多的步驟。也沒有被限制誰先可以用誰先不能用的情形。
ScrollView {
    // 你的內容
}
.refreshable {}

我們做一個這樣子的 UI
struct ContentView: View {
    @State private var items = [1, 2, 3]
    var body: some View {
        ScrollView {
            navigation()
            ForEach(items, id: \.self) { day in
                HStack {
                    Text("Day: \(day)")
                    Spacer()
                }
                .padding()
                .background(
                    RoundedRectangle(cornerRadius: 5)
                        .stroke()
                        .foregroundColor(.gray)
                )
                .padding(.horizontal, 8)
            }
        }
    }
    
    func navigation() -> some View {
        HStack {
            Text("鐵人賽文章")
                .fontWeight(.bold)
            Spacer()
            Text("總篇數 \(items.count)")
            Divider()
            Button {
                reset()
            } label: {
                Text("重置")
            }
        }
        .padding()
    }
    
    private func reset() {
        items = [1, 2, 3]
    }
    /// 利用 async-await 模擬網路存取,內部做了
    /// 1. 延時 1 秒
    /// 2. 在 items 前面加上三個新的數字
    private func reload() async throws {
        let second: UInt64 = 1_000_000_000
        try await Task.sleep(nanoseconds: second)
        let count = items.count
        items = [count + 1, count + 2, count + 3] + items
    }
}
像是這樣,在 ScrollView 後面加上 refreshable ,內部則呼叫模擬網路存取的 reload 方法。
ScrollView {
    // 省略
}
// 加上 refreshable ,呼叫模擬網路存取的 `reload` 方法
.refreshable {
    do {
        try await reload()
    } catch {
        print("Error: \(error)")
    }
}
refreshable 的 indicator 會根據 await 執行的結果而結束顯示,不用項 UIRefreshControl 那樣,像下面的程式碼那樣需要我們去停止它,非常方便。
refreshControl.endRefreshing()

到這裡就是在 SwiftUI 中如何使用 EnvironmentObject 。
那今天的 SwiftUI 的大大小小就到這邊,以上,明天見!
本篇使用到的 UI 元件和 modifiers 基本上沒有受到版本更新影響
因此 Xcode 14 等環境下使用也是沒問題的。