List的常规使用
List对标UIKit中的UITabView,而UITabView是我们在App开发中常用的控件之一。
1.List 静态数据展示
var body: some View {
List{
Text("测试展示1")
Text("测试展示2")
Text("测试展示3")
Text("测试展示4")
Text("测试展示5")
}
}
2.动态数据展示和List多选
当然大部分情况下 我们创建的list数据都是动态的,这时候需要我们自己自定义展示的视图和驱动UI展示的模型数据,下面是设置List多选的实现,具体效果如下
struct Ocean: Identifiable, Hashable{
let name: String
let id = UUID()
}
private var oceans = [
Ocean(name: "Pacific"),
Ocean(name: "Atlantic"),
Ocean(name: "Indian"),
Ocean(name: "Southern"),
Ocean(name: "Arctic")
]
/// 记录选中的区域
@State private var multiSelection = Set<UUID>()
var body: some View {
VStack{
NavigationView {
List(oceans,selection: $multiSelection){
Text($0.name)
}
.navigationTitle("Oceans")
.toolbar{
EditButton()
}
}
Text("已选择\(multiSelection.count)").foregroundColor(.red)
}
}
3.List数据删除和移动
List数据删除和上下移动也是常用的功能之一,在SwiftUI上实现更加便捷。先看下效果
@State private var fruits = [
"Apple",
"Banana",
"Papaya",
"Mango",
"orange",
"pineapple"
]
/// 移动和删除
func removeAndDeleteRow() -> some View {
NavigationView {
List{
ForEach(fruits,id: \.self){
Text($0)
}
.onDelete { fruits.remove(atOffsets: $0)}
.onMove { fruits.move(fromOffsets: $0, toOffset: $1)}
}
.navigationTitle("Oceans")
.toolbar{
EditButton()
}
}
}
4.List的分组展示
List设置Group展示样式,SwiftUI提供了三种展示样式 .plain ,.group,.automatic,前两种都和之前的样式一样,最后一种是左右会添加一个边距的效果,可以自己设置看下具体样式。List实现分组设置要添加Section组件.
构造假数据
/// 设置分组展示
func setListSection() -> some View {
NavigationView{
List{
ForEach(1..<6){ va in
Section(header: Text(fruits[va])) {
ForEach(1..<5){ i in
Text("测试展示数据\(i)")
}
}
}
}
//设置list展示的样式
.listStyle(.automatic)
.navigationTitle("测试分组展示")
}
}
5.List设置树状结构视图
展示可折叠list,设置层级展示的树状结构 关键在于设置数据模型。分层列表需要设置树结构数据和children提供关键路径的参数来创建任意深度的分层列表。
func setFileFoldStyle() -> some View {
struct FileItem: Hashable, Identifiable, CustomStringConvertible {
var id: Self { self }
var name: String
var children: [FileItem]? = nil
var description: String {
switch children {
case nil:
return "📄 \(name)"
case .some(let children):
return children.isEmpty ? "📂 \(name)" : "📁 \(name)"
}
}
}
let fileHierarchyData: [FileItem] = [
FileItem(name: "users", children:
[FileItem(name: "user1234", children:
[FileItem(name: "Photos", children:
[FileItem(name: "photo001.jpg"),
FileItem(name: "photo002.jpg")]),
FileItem(name: "Movies", children:
[FileItem(name: "movie001.mp4")]),
FileItem(name: "Documents", children: [])
]),
FileItem(name: "newuser", children:
[FileItem(name: "Documents", children: [])
])
]),
FileItem(name: "private", children: nil)
]
return NavigationView{
List(fileHierarchyData,children:\.children){ item in
Text(item.description)
}.navigationTitle(Text("可折叠list"))
}
}
2.Form的基本使用
Form和List在UI呈现上基本上都是一个可以滚动的视图,对数据进行分类分组进行展示。常用的有设置或检查页面中。
另外 Form 没有 .listStyle 可以设置多个样式,就是一个只有group样式的List组件。
enum NotifyMeAboutType: String {
case directMessages = "directMessages"
case mentions = "mentions"
case anything = "anything"
}
enum ProfileImageSize: String {
case large = "Large size"
case medium = "Medium size"
case small = "Small size"
}
struct TestFormView: View {
@State var sendReadReceipts = false
@State var playNotificationSounds = true
@State var notifyMeAbout: NotifyMeAboutType = .directMessages
@State var profileImageSize: ProfileImageSize = .large
@State var date: Date = Date()
var body: some View {
NavigationView{
Form {
Section(header: Text("Notifications")) {
DatePicker(
"Start Date",
selection: $date,
displayedComponents: [.date]
)
.datePickerStyle(.automatic)
Picker("Notify Me About", selection: $notifyMeAbout) {
Text("Direct Messages").tag(NotifyMeAboutType.directMessages)
Text("Mentions").tag(NotifyMeAboutType.mentions)
Text("Anything").tag(NotifyMeAboutType.anything)
}.pickerStyle(.automatic)
Toggle("Play notification sounds", isOn: $playNotificationSounds)
Toggle("Send read receipts", isOn: $sendReadReceipts)
}
Section(header: Text("User Profiles")) {
Picker("Profile Image Size", selection: $profileImageSize) {
Text("Large").tag(ProfileImageSize.large)
Text("Medium").tag(ProfileImageSize.medium)
Text("Small").tag(ProfileImageSize.small)
}.pickerStyle(.menu)
/// picker有多个style 可以逐一试试其效果
Button("Clear Image Cache") {}
}
}
.navigationTitle("测试来了")
}
}
}