SwiftUI的List View和UIKit中的UITableView很相似,它可以根据你的需求加载静态或者动态数据。不同的是,List使用起来更加的简单:我们不需要在storyboard或者Xib中创建cell,也不需要使用代码注册cell,不需要告诉它要有多少行内容,当然也不需要dequeue cell以及手动设置cell等等。
一、创建一个静态数据列表
想要创建一个静态数据列表,你首先需要确定每一个cell的样式。我们可以自定义一个简单的cell,代码如下:
struct StreetRow: View {
var name: String
var body: some View {
Text("The street name is \(name)")
}
}
这样我们就定义了一个简单的cell,cell上只有一行文字,现在可以创建一个List View,并添加你需要的数量的cell,像这样:
struct ListViewDemo: View {
var body: some View {
List{
//当然可以有多种不同的Row哦
StreetRow(name: "The Lodon Street")
StreetRow(name: "The Joe's Street")
StreetRow(name: "The House Street")
}
}
}
这样就创建了一个最简单的列表,这里不得不说swiftUI确实是强大,短短几行代码就可以创建出UITableView需要书写大量代码才能看到的效果。
二、创建一个动态数据列表
如果想动态的生成items,比如根据接口返回的数据生成列表,就需要用到动态列表。按照UIKit中的习惯,首先我们需要一个model存储这些数据,SwiftUI也类似,我们需要创建一个Street的结构体,并遵循Identifiable协议,此协议中只有一个必须的属性:id,它用来让SwiftUI区分不同的item。
struct Street: Identifiable {
var id = UUID()
var name: String
}
这里我们给id初始化为UUID():
struct StreetRow: View {
var street: Street
var body: some View {
Text("The street name is \(street.name)")
}
}
最后在准备我们需要的数据,并让其动态加载到页面上,实际开发中往往是从接口返回的数据,这里准备了几条假数据来说明使用:
struct ListViewDemo: View {
var body: some View {
let street1 = Street(name: "The Lodon Street")
let street2 = Street(name: "The Joe's Street")
let street3 = Street(name: "The House Street")
//数据数组
let streets = [street1, street2, street3]
return List(streets){ street in
StreetRow(street: street)
}
}
}
SwiftUI会根据streets数组中的数据每次执行闭包创建cell,最终显示页面。其实针对这种情况下还有更简单的创建List的方式:
return List(streets, rowContent: StreetRow.init)
实际上List有很多的创建的方式,剩下的大家可以慢慢探索哦。
三、设置左滑删除cell
struct ListViewDemo: View {
//数据数组
@State private var streets = [Street(name: "The Lodon Street"), Street(name: "The Joe's Street"), Street(name: "The House Street")]
var body: some View {
func deleteRow(at offsets:IndexSet) {
streets.remove(atOffsets:offsets)
}
return List{
ForEach(streets, id: \.self) { street in
StreetRow(street: street)
}.onDelete(perform: deleteRow)
}
}
}
实现起来是不是很简单,但是需要注意的是:使用ForEach结构体,需要保证street遵守Hashable协议:
struct Street: Identifiable,Hashable {
var id = UUID()
var name: String
}
这里你可能会好奇,删除掉cell后数据是怎么同步并实时更新页面的,我们注意到数据源streets使用了@State修饰,这就是数据绑定,后面的章节会有专门的讲解哦。
四、List添加section分组以及设置grouped类型
struct ListViewDemo: View {
var body: some View {
return List{
Section(header:Text("some streets one"), footer: Text("Fotter1")){
TaskRow()
TaskRow()
TaskRow()
}
Section(header:Text("some streets two"), footer: Text("Fotter2")){
TaskRow()
TaskRow()
TaskRow()
}
}
}
}
struct TaskRow: View {
var body: some View {
Text("Task data goes here")
}
}
和UITableView一样,你可以让数据分组显示,并为每一个section添加header和fotter,效果如下:
在UITableView中我们可以设置plain和grouped两种样式,而默认是plain样式,SwiftUI也一样。在swiftUI中设置grouped样式很简单,只需要为list添加相应的listStyle modifier:
struct ListViewDemo: View {
var body: some View {
return List{
Section(header:Text("some streets one"), footer: Text("Fotter1")){
TaskRow()
TaskRow()
TaskRow()
}
Section(header:Text("some streets two"), footer: Text("Fotter2")){
TaskRow()
TaskRow()
TaskRow()
}
}.listStyle(GroupedListStyle())
}
}
效果如下:
五、点击cell跳转的实现
首先需要新建一个详情页ListViewDetial,因为只是演示跳转,所以里面使用默认的代码。
struct ListViewDemo: View {
var body: some View {
let streets = [
Street(name: "The Lodon Street"),
Street(name: "The Joe's Street"),
Street(name: "The House Street")
]
return NavigationView{
List(streets){ street in
NavigationLink(destination:ListViewDetial()){
StreetRow(street: street)
}
}.navigationBarTitle("Streets")
}
}
}
实现跳转的重点是:List包裹在NavigationView中,并且cell也需要包裹进NavigationLink中,并设置destination属性,其他的和上面介绍的没有区别。
好了,本篇文章介绍了swiftUI中List的创建,使用,设置以及点击跳转,基本包含了List的日常使用。每天进步一点点,成为更好的自己!有问题欢迎留言交流,欢迎关注!