SwiftUI List 列表操作教學

List 不僅僅是顯示資料,它還內建了強大的互動功能,最常用的就是左滑刪除 (Swipe to Delete)拖曳排序 (Drag and Drop to Move)

左滑刪除 (onDelete)

要啟用刪除功能,你需要對 ForEach (注意:不是對 List) 使用 .onDelete 修飾符。

struct ContentView: View {
    @State private var fruits = ["Apple", "Banana", "Orange", "Grape"]
    
    var body: some View {
        NavigationStack {
            List {
                ForEach(fruits, id: \.self) { fruit in
                    Text(fruit)
                }
                .onDelete(perform: deleteFruit) // 綁定刪除方法
            }
            .navigationTitle("水果列表")
        }
    }
    
    // 刪除方法的簽名必須符合 (IndexSet) -> Void
    func deleteFruit(at offsets: IndexSet) {
        fruits.remove(atOffsets: offsets)
    }
}

拖曳排序 (onMove)

要啟用排序功能,同樣需要對 ForEach 使用 .onMove 修飾符。此外,必須要在 Edit Mode (編輯模式) 下才能看到拖曳手柄。

我們可以加入一個 EditButton 來切換編輯模式。

struct ContentView: View {
    @State private var fruits = ["Apple", "Banana", "Orange", "Grape"]
    
    var body: some View {
        NavigationStack {
            List {
                ForEach(fruits, id: \.self) { fruit in
                    Text(fruit)
                }
                .onMove(perform: moveFruit) // 綁定移動方法
            }
            .navigationTitle("水果列表")
            .toolbar {
                EditButton() // 內建的編輯按鈕
            }
        }
    }
    
    func moveFruit(from source: IndexSet, to destination: Int) {
        fruits.move(fromOffsets: source, toOffset: destination)
    }
}

下拉更新 (Refreshable)

在 iOS 15 之後,SwiftUI 原生支援下拉更新。只需要對 List 使用 .refreshable 即可。

List(fruits, id: \.self) { fruit in
    Text(fruit)
}
.refreshable {
    // 執行異步更新操作
    await loadNewFruits()
}

掌握了這些操作,你就可以製作出功能完整的管理介面了。