如何移除SwiftUI List中首个元素上方的默认分隔线
问题描述
我实现了一个遍历数据库中数据的简单List,代码如下:
List { TextField("Search", text: $textFieldSearch) .padding(7) .background(Color(.systemGray6)) .cornerRadius(8) ForEach((bookViewModel.books).filter({ "\($0)".contains(textFieldSearch) || textFieldSearch.isEmpty })) { book in NavigationLink(destination: ChapterView(book: book), label: { HStack { Text("\(book.name)") } .padding() }) } } .onAppear { bookViewModel.fetchBooks() }
当前遇到的问题是:TextField上方会出现一条分隔线,我推测这是将TextField放在List内部导致的。如果我把TextField移到List外部上方,它会占据整个屏幕,无法显示下方ForEach渲染的内容,同时样式也无法和列表保持统一。请问解决该问题的最优方案是什么?
问题截图:
最优解决方案
最优方案是直接隐藏搜索框所在行的List默认分隔线,无需改动原有布局结构,既可以保留搜索框跟随列表滚动的交互,也能完美和列表样式统一,仅需给TextField新增一行.listRowSeparator(.hidden)修饰符即可:
List { TextField("Search", text: $textFieldSearch) .padding(7) .background(Color(.systemGray6)) .cornerRadius(8) // 隐藏当前行的分隔线 .listRowSeparator(.hidden) // 可选:可自定义搜索框的行边距,和下方列表项样式统一 .listRowInsets(EdgeInsets(top: 8, leading: 16, bottom: 8, trailing: 16)) ForEach((bookViewModel.books).filter({ "\($0)".contains(textFieldSearch) || textFieldSearch.isEmpty })) { book in NavigationLink(destination: ChapterView(book: book), label: { HStack { Text("\(book.name)") } .padding() }) } } .onAppear { bookViewModel.fetchBooks() }
兼容与备选方案
1. iOS15以下版本兼容方案
如果需要适配iOS15以下的系统,可以隐藏整个List的全局分隔线,再按需给列表项手动添加分隔线:
List { TextField("Search", text: $textFieldSearch) .padding(7) .background(Color(.systemGray6)) .cornerRadius(8) .listRowInsets(EdgeInsets(top: 8, leading: 16, bottom: 8, trailing: 16)) ForEach((bookViewModel.books).filter({ "\($0)".contains(textFieldSearch) || textFieldSearch.isEmpty })) { book in NavigationLink(destination: ChapterView(book: book), label: { VStack(spacing: 0) { HStack { Text("\(book.name)") } .padding() // 手动给列表项添加分隔线 Divider() .padding(.leading) } }) .listRowSeparator(.hidden) } } .listStyle(.plain) .onAppear { bookViewModel.fetchBooks() // 全局隐藏UITableView分隔线,仅iOS15以下生效 UITableView.appearance().separatorStyle = .none }
2. 搜索框固定顶部方案
如果需要搜索框固定在页面顶部不跟随列表滚动,可以用VStack嵌套搜索框和List,给List设置更高的布局优先级解决空间占满问题:
NavigationStack { VStack(spacing: 0) { TextField("Search", text: $textFieldSearch) .padding(7) .background(Color(.systemGray6)) .cornerRadius(8) .padding(.horizontal) .padding(.vertical, 8) .background(Color(.systemBackground)) List { ForEach((bookViewModel.books).filter({ "\($0)".contains(textFieldSearch) || textFieldSearch.isEmpty })) { book in NavigationLink(destination: ChapterView(book: book), label: { HStack { Text("\(book.name)") } .padding() }) } } // 提高List的布局优先级,避免被TextField挤压显示空间 .layoutPriority(1) } .navigationTitle("书籍列表") } .onAppear { bookViewModel.fetchBooks() }
内容的提问来源于stack exchange,提问作者erikvm
相关产品推荐
相关产品推荐

