listView在APP交互上是一个很高频的容器组件了,在传统的UIKit中一般是给tableview或者collectionView设置delegate,controller完成cell的制作和UI束缚,控制列表的翻滚交互和UI风格。在swiftUI中该如何控制list的这些特性,本文做一个简略的记载。
静态的listview
假如要展现的是一些固定数据的且数据量不大的list,简略几行代码就能完成
var body: some View {
List{
Text("Hello, World!")
Text("Hello, World!")
Text("Hello, World!")
}
}
List默许的款式是InsetGroupedListStyle,作用如下
分组的listview
SwiftUI里用Sectoin表明一个分组
Section {
TextField("输入名字", text: $username)
Toggle(isOn: $isPrivate) {
Text("隐私")
}
Button{}label: {
Text("退出")
}
} header: {
Text("个人")
}
Section {
Slider(value: $fontSize, in: 1...10)
Picker("主题", selection: $appearance) {
Text("Dark").tag(AppearanceStyle.dark)
Text("Light").tag(AppearanceStyle.light)
Text("Auto").tag(AppearanceStyle.auto)
}
} header: {
Text("主题")
}
Section {
HStack{
Text("版本")
Spacer()
Text("1.0.0")
}
} header: {
Text("关于")
}
}
动态的listview
listview的呈现大部分情况下都是依据服务的回来的数据动态体现的,这里mock一个数组模拟api的回来数据,显现一个生果的列表。
struct Food{
var name: String
var icon: String
var isFavorite: Bool
static func preview() -> [Food]{
return [
Food(name: "苹果", icon: "", isFavorite: true),
Food(name: "草莓", icon: "", isFavorite: true),
Food(name: "香蕉", icon: "", isFavorite: true),
Food(name: "樱桃", icon: "", isFavorite: true),
Food(name: "葡萄", icon: "", isFavorite: true),
Food(name: "西瓜", icon: "", isFavorite: true),
]
}
}
直接在List中显现一个arr会报错 「Initializer ‘init(_:rowContent:)’ requires that ‘Food’ conform to ‘Identifiable’」,意思就是你显现的Model不具有仅有性,此时能够供给一个名为id的特点,指定一个Model里的特点作为仅有标识就好了。
List{
let fruits = Food.preview()
List(fruits, id: \.name) { food in
Text(food.name)
}
这里供给的id是fruit的name,mock的数据里是仅有的,但真实的项目里不会用这种性质的字段最为id,一般会给Model通过完成Identifiable的方式扩展一个UUID的id特点来处理。
struct Food: Identifiable{
......
let id = UUID()
}
这个时候你的list中不供给id特点也不会报错了,页面能正常展现
创立自定义cell
SwiftUI里不需要像在UIKit下去创立一个集成UITableViewCell的view,只要在List中指定要显现的UI组件即可,假如UI比较复杂,能够抽取出一个独立的view。
struct FoodRow: View{
let food: Food
var body: some View{
HStack{
Text(food.icon).font(.title)
Text(food.name)
Spacer()
Image(systemName: food.isFavorite ? "heart.fill" : "heart")
}
}
}
设置group款式,以及group的header和footer
新增一个array,分组显现为生果和零食。你能够往List里随意的添加section来完成分组,section有自定义的header和footer特点来显现组的头尾信息,运用默许的InsetGroupedListStyle款式。或者你也能够用DisclosureGroup来显现一个可折叠的分组作用
数据的添加和删除
先说删除,主页显现数据的array标示为@State,其次list有一个delete的方法,传入一个block回调
@inlinable public func onDelete(perform action: ((IndexSet) -> Void)?) -> some DynamicViewContent
添加数据,直接在barItem添加点击事件,往数据里新增一条记载就好
toolbar {
Button {
fruits.append(Food(name: "未知food", icon: "⚠️", isFavorite: false))
} label: {
Text("新增")
}
}