本文為 Eul 樣章,如果您喜歡,請移步 AppStore/Eul 查看更多內容,
Eul 是一款 SwiftUI & Combine 教程 App(iOS、macOS),以文章(文字、圖片、代碼)配合真機示例(Xcode 12+、iOS 14+,macOS 11+)的形式呈現給讀者,筆者意在盡可能使用簡潔明了的語言闡述 SwiftUI & Combine 相關的知識,使讀者能快速掌握并在 iOS 開發中實踐,
List
構建
基礎構建方法
List 最基本的構建方法:
List {
Text("Sun")
Text("Cloud")
Text("Snow")
}
資料源
通常我們的串列并非靜態,而是與動態的資料源系結的,List 可以通過傳入 data 來實作,不過這里的 data 需要遵循 Identifiable 協議,這樣才能保證資料的唯一性,
我們先對天氣作如下定義:
struct Weather: Identifiable {
let id = UUID()
let name: String
let icon: String
}
id 是協議要求實作的屬性(遵循 Hashable 協議),我們也可以在實體初始化時傳入 0, 1, 2, 3...只要是沒有沖突的哈希值都可以,這里我們有個簡單的處理方法,就是通過 UUID() 生成惟一值,在初始化時可以省去傳參,
然后我們添加資料源:
@State private var weathers = [
Weather(name: "Sunshine", icon: "sun.max.fill"),
Weather(name: "Cloud", icon: "cloud"),
Weather(name: "Snow", icon: "snow"),
Weather(name: "Rain", icon: "cloud.rain.fill")
]
生成 List:
List(weathers) { v in
Label(v.name, systemImage: v.icon)
}
可展開串列
List 可以通過樹形結構的資料源直接構建可展開的串列,比如我們定義如下可展開的天氣物件:
struct ExpandWeather: Identifiable {
let id = UUID()
var name: String
var icon: String
var weathers: [ExpandWeather]?
}
該結構體內嵌的 weathers 的元素型別就是它本身,而且是可選型別,我們構造如下資料:
let expandWeather: [ExpandWeather] = [
ExpandWeather(name: "Weather", icon: "", weathers: [
ExpandWeather(name: "Sunshine", icon: "sun.max.fill"),
ExpandWeather(name: "Cloud", icon: "cloud"),
ExpandWeather(name: "Snow", icon: "snow"),
ExpandWeather(name: "Rain", icon: "cloud.rain.fill")
])
]
然后通過如下方法構建視圖:
List(expandWeather, children: \.weathers) { weather in
Label(weather.name, systemImage: weather.icon)
}
最后得到的就是一個可以展開的串列,當然我們可以構造更加復雜的多級展開串列,其原理是一樣的,都是在子資料中嵌套更多資料型別相同的子資料,
樣式
List 有多種樣式,系統為我們提供了多種 ListStyle,其中,iOS 比較常用的除了系統默認樣式外,還有 GroupedListStyle 和 InsetGroupedListStyle,
ForEach
基本使用
ForEach 能通過回圈從集合資料中快速構建視圖,集合資料 data 可以是 Range<Int> 型別,也可以是元素遵循 Identifiable 協議的陣列,
比如:
ForEach(0..<2) { idx in
Text("\(idx)")
}
或者,我們仍然以上文的 weathers 作為 data ,
ForEach(weathers) { weather in
Text(weather.name)
}
ForEach 里有個引數 id,它用來保證資料的唯一性,上例中我們并沒有顯示地呼叫它,因為對 Range
如果我們只是想通過一個普通的字串陣列去實作回圈創建視圖,那么 id 可以顯示指定為 \.self,即使用字串本身作為 id 來保證資料的唯一性,
ForEach(["A", "B"], id: \.self) { str in
Text(str)
}
編輯操作
還記得我們前面提到過得 EditButton 嗎?之前我們并沒有具體講解它的用法,現在我們可以見到它的具體使用了,
ForEach 和 List 配合使用,可以輕松地對串列進行編輯操作:delete、move,還是以 weathers 作為資料源,我們構建串列視圖:
var body: some View {
List {
ForEach(weathers) { v in
Label(v.name, systemImage: v.icon)
}
.onDelete(perform: onDelete)
.onMove(perform: onMove)
}
.navigationBarItems(trailing: EditButton())
}
func onDelete(offsets: IndexSet) {
weathers.remove(atOffsets: offsets)
}
func onMove(fromOffsets: IndexSet, toOffset: Int) {
weathers.move(fromOffsets: fromOffsets, toOffset: toOffset)
}
EditButton 終于登場了,試試對串列進行編輯操作,
這里的編輯操作只是單選操作,如果我們要多選呢?可以在 List 中系結 selection 資料,通過它對多條資料同時操作,這里就不舉例了,讀者可以按照這個思路去實作,
ScrollView
ScrollView 只有一個構建方法:
init(_ axes: Axis.Set = .vertical, showsIndicators: Bool = true, content: () -> Content)
使用也簡單,這里不再贅述,
ScrollViewReader
ScrollViewReader 的回呼閉包回傳的是一個 ScrollViewProxy 實體,它只有一個實體方法 scrollTo(),該 方法能夠使 ScrollView 滑動到指定的位置,對 List 也同樣適用,
scrollTo() 還可以傳入 anchor 引數控制更精確的滑動,比如示例所示為:sr.scrollTo(70, anchor: .center),
如果需要給滑動添加影片效果,只需要在 withAnimation 的閉包中呼叫 scrollTo() 即可,
本文為 Eul 樣章,如果您喜歡,請移步 AppStore/Eul 查看更多內容,
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/286155.html
標籤:iOS
下一篇:SwiftUI 簡明教程之容器
