在 iOS 開發(fā)中,我們經(jīng)常需要展示可滾動(dòng)的內(nèi)容列表,并在點(diǎn)擊某個(gè)條目后跳轉(zhuǎn)到詳情頁(yè)面。在 SwiftUI 中,這一功能變得非常簡(jiǎn)單。通過(guò) List 和 NavigationStack 組件,我們可以以聲明式的方式構(gòu)建復(fù)雜的導(dǎo)航和列表界面。
一. 使用 List 展示靜態(tài)數(shù)據(jù)
SwiftUI 中的 List 是構(gòu)建列表的核心組件,類似于 UIKit 中的 UITableView。我們來(lái)看一個(gè)基礎(chǔ)示例:
import SwiftUI
struct ContentView: View {
let fruits = ["蘋果", "香蕉", "橘子", "梨子"]
var body: some View {
NavigationStack {
List(fruits, id: \.self) { fruit in
Text(fruit)
}
.navigationTitle("水果列表")
}
}
}
說(shuō)明:
-
List(fruits, id: \.self):根據(jù)數(shù)組fruits渲染列表。 -
NavigationStack包裹整個(gè)界面,為跳轉(zhuǎn)提供導(dǎo)航上下文。 -
.navigationTitle設(shè)置導(dǎo)航欄標(biāo)題。
二. 列表點(diǎn)擊跳轉(zhuǎn)詳情頁(yè)
我們可以為列表的每一項(xiàng)添加導(dǎo)航跳轉(zhuǎn)動(dòng)作。比如點(diǎn)擊某個(gè)水果后跳轉(zhuǎn)到一個(gè)詳情視圖:
import SwiftUI
struct FruitDetailView: View {
let fruitName: String
var body: some View {
Text("這是 \(fruitName) 的詳情頁(yè)")
.font(.largeTitle)
.padding()
}
}
struct ContentView: View {
let fruits = ["蘋果", "香蕉", "橘子", "梨子"]
var body: some View {
NavigationStack {
List(fruits, id: \.self) { fruit in
NavigationLink(destination: FruitDetailView(fruitName: fruit)) {
Text(fruit)
}
}
.navigationTitle("水果列表")
}
}
}
說(shuō)明:
-
NavigationLink是 SwiftUI 中用于實(shí)現(xiàn)跳轉(zhuǎn)的控件。 - 每個(gè)
NavigationLink指向一個(gè)新的FruitDetailView頁(yè)面。 - 無(wú)需手動(dòng)維護(hù)導(dǎo)航棧,SwiftUI 自動(dòng)處理返回邏輯。
三. 使用結(jié)構(gòu)體模型構(gòu)建列表
我們不必總是用 String 類型來(lái)構(gòu)建列表,通常會(huì)使用結(jié)構(gòu)體模型:
struct Fruit: Identifiable {
let id = UUID()
let name: String
let description: String
}
let fruitList = [
Fruit(name: "蘋果", description: "紅色水果,富含維生素C"),
Fruit(name: "香蕉", description: "黃色水果,富含鉀"),
Fruit(name: "橘子", description: "橙色水果,汁水豐富")
]
struct ContentView: View {
var body: some View {
NavigationStack {
List(fruitList) { fruit in
NavigationLink(destination: Text(fruit.description)) {
Text(fruit.name)
}
}
.navigationTitle("水果百科")
}
}
}
-
Identifiable協(xié)議允許 SwiftUI 自動(dòng)識(shí)別每個(gè)元素的唯一性。 - 結(jié)構(gòu)體模型使得數(shù)據(jù)更具拓展性,便于后續(xù)展示圖片、價(jià)格等屬性。
四. 動(dòng)態(tài)添加與刪除列表項(xiàng)
我們可以使用 @State 來(lái)管理列表數(shù)據(jù),從而實(shí)現(xiàn)增刪功能:
struct ContentView: View {
@State private var fruits = ["蘋果", "香蕉", "橘子"]
var body: some View {
NavigationStack {
List {
ForEach(fruits, id: \.self) { fruit in
Text(fruit)
}
.onDelete { indexSet in
fruits.remove(atOffsets: indexSet)
}
}
.navigationTitle("可編輯水果列表")
.toolbar {
EditButton()
}
}
}
}
-
ForEach和onDelete組合實(shí)現(xiàn)滑動(dòng)刪除。 -
EditButton()提供編輯模式切換按鈕。