如何在不使用 ForEach 的情况下从 SwiftUI 中的列表中删除行分隔符?
How to remove the line separators from a List in SwiftUI without using ForEach?
我有显示自定义行列表的代码。
struct ContentView : View {
var body: some View {
VStack(alignment: .leading) {
List(1...10) {_ in
CustomRow()
}
}
}
}
但是,我想删除每一行上的线。我尝试不使用 List
而是在 ScrollView
中使用 ForEach
但它完全删除了所有样式,包括其填充和边距。我只想删除这些行,没有别的。
请帮忙,谢谢。
iOS 15+:
只需将 .listRowSeparator(.hidden)
作为修饰符添加到包含在 List
中的视图中。 https://developer.apple.com/documentation/swiftui/texteditor/listrowseparator(_:edges:)
List {
ForEach(garage.cars) { car in
Text(car.model)
.listRowSeparator(.hidden)
}
}
iOS 仅 13:
在 List
出现之前在代码中的任何位置添加 UITableView.appearance().separatorColor = .clear
应该可以。虽然此解决方案删除了分隔符,但请注意所有 List
实例都将绑定到此样式,因为目前没有官方方法只能删除特定实例的分隔符。您可以在 onAppear
中 运行 这段代码并在 onDisappear
中撤消它以保持样式不同。
另请注意,此代码假定 Apple 使用 UITableView
来支持 List
,这在 iOS 14 SDK 中并非如此。希望他们将来添加官方 API。感谢 https://twitter.com/singy/status/1169269782400647168.
iOS 15:
今年 Apple 推出了一个新修饰符 .listRowSeparator
,可用于设置分隔符的样式。你可以通过 .hidden
来隐藏它:
List {
ForEach(items, id:\.self) {
Text("Row \([=10=])")
.listRowSeparator(.hidden)
}
}
iOS 14:
您可以考虑在 ScrollView
中使用 LazyVStack
(因为 iOS 不 支持 SwiftUI 的 UIAppearance
不再列出)。
iOS 13:
⚠️ This method is deprecated and it's not working from iOS 14
在 SwiftUI 的 List
后面有一个 UITableView
用于 iOS 13。因此要删除
额外的分隔符(列表下方):
您需要 tableFooterView
并删除
所有分隔符(包括实际分隔符):
你需要 separatorStyle
才能成为 .none
用法示例
init() {
if #available(iOS 14.0, *) {
// iOS 14 doesn't have extra separators below the list by default.
} else {
// To remove only extra separators below the list:
UITableView.appearance().tableFooterView = UIView()
}
// To remove all separators including the actual ones:
UITableView.appearance().separatorStyle = .none
}
var body: some View {
List {
Text("Item 1")
Text("Item 2")
Text("Item 3")
}
}
请注意,默认情况下,静态列表不会在列表下方显示额外的分隔符
查看 SwiftUI-Introspect。它公开了底层的 UIKit/AppKit 视图。
iOS 仅 13 个版本:
在这种情况下,您可以直接操作 UITableView(无需通过外观代理更改所有 table 视图):
import Introspect
:
:
List {
...
}.introspectTableView { tableView in
tableView.separatorStyle = .none
}
做类似的事情:
UITableView.appearance().separatorColor = .clear
有效,但在很多情况下我不推荐这样做。这些是全局更改 - 即它们将影响 UITableView 的 all 个实例。如果您有多个需要不同样式的 UITableView,这就是一个问题。或者,如果您正在开发一个框架,那么使用您的框架的客户也会继承这些更改!
更安全的解决方案是仅针对位于指定容器内的 UITableView。幸运的是 appearance
api 给了我们一个具体的方法:
UITableView.appearance(whenContainedInInstancesOf: [UIHostingController<YourSwiftUiViewHere>.self]).separatorColor = .clear
使用 ScrollView?
代表您列表的某个州
@State var menuItems: [String] = ["One", "Two", "Three"]
SwiftUI
ForEach
循环 ScrollView
ScrollView {
ForEach(self.menuItems, id: \.self) { item in
Text(item)
}
}
iOS 仅 13 个版本:
虽然这些答案在技术上是正确的,但根据我的经验,它们会影响 List
或 Form
全局(在整个应用程序中)。
我发现至少在我的应用程序中解决此问题的一种 hacky 方法是将以下代码添加到应用程序的“主要”内容视图:
.onAppear(perform: {
UITableView.appearance().separatorStyle = .none
})
然后在您想要分隔线的任何其他视图上将其添加到 List
或 Form
视图的末尾
.onAppear(perform: {
UITableView.appearance().separatorStyle = .singleLine
})
这似乎将单行分隔符添加到主内容视图上方的任何视图 sheet。同样,这都是我最近的 SwiftUI 体验的轶事。
根据我的经验,我只需将 .onAppear(... = .singleLine)
方法添加到我的“详细信息”视图之一,分隔线就会出现在所有随后显示的视图中。
编辑: 另一个注意事项,因为这个答案继续受到关注。我 posted 的这个解决方案并没有解决所有情况,在某些情况下,它当然也没有为我解决。我最终使用 Introspect for SwiftUI 解决了整个应用程序中的这个问题。
我希望这能消除人们遇到此问题时的一些困惑和沮丧 post。
IOS 14
IOS 14 beta 目前没有隐藏分隔符的解决方案。
如果您不需要可编辑的 List
,您应该在 ScrollView
中使用 LazyVStack
。
但是如果你想留在List
。我在 samwarner 的 Apple 论坛上找到了解决方案。 https://developer.apple.com/forums/thread/651028
这是一个临时解决方案。在某些情况下,您可能需要调整插图。
这是它的实现:
struct HideRowSeparatorModifier: ViewModifier {
static let defaultListRowHeight: CGFloat = 44
var insets: EdgeInsets
var background: Color
init(insets: EdgeInsets, background: Color) {
self.insets = insets
var alpha: CGFloat = 0
UIColor(background).getWhite(nil, alpha: &alpha)
assert(alpha == 1, "Setting background to a non-opaque color will result in separators remaining visible.")
self.background = background
}
func body(content: Content) -> some View {
content
.padding(insets)
.frame(
minWidth: 0, maxWidth: .infinity,
minHeight: Self.defaultListRowHeight,
alignment: .leading
)
.listRowInsets(EdgeInsets())
.background(background)
}
}
extension EdgeInsets {
static let defaultListRowInsets = Self(top: 0, leading: 16, bottom: 0, trailing: 16)
}
extension View {
func hideRowSeparator(insets: EdgeInsets = .defaultListRowInsets, background: Color = .white) -> some View {
modifier(HideRowSeparatorModifier(insets: insets, background: background))
}
}
最后,这里是列表中的实现。您必须在列表单元格中添加 .hideRowSeparator()
。
struct CustomRow: View {
let text: String
var body: some View {
HStack {
Text(self.text)
Image(systemName: "star")
}
}
}
struct ContentView : View {
@State private var fruits = ["Apple", "Orange", "Pear", "Lemon"]
var body: some View {
VStack(alignment: .leading) {
List {
ForEach(self.fruits, id: \.self) { str in
CustomRow(text: str)
.hideRowSeparator()
}
}
}
.padding(.top)
}
}
我在 iOS14 开始了一个项目来解决这个问题,因为 iOS 13 变通办法不再有效。它允许设置分隔符样式、分隔符颜色和分隔符插入。
隐藏列表中的分隔符
List { <content> }
.listSeparatorStyle(.none)
显示带有可配置颜色和插图的单个分隔线
List { <content> }
.listSeparatorStyle(.singleLine, color: .red, inset: EdgeInsets(top: 0, leading: 50, bottom: 0, trailing: 20)
所有答案都告诉你使用ScrollView(这也是我推荐的)
但如果您想使用 List 并希望删除分隔线..
安装 SwiftPM:https://github.com/siteline/SwiftUI-Introspect
样本:
List {
Text("Item 1")
Text("Item 2")
}
.introspectTableView { tableView in
tableView.separatorStyle = .none
}
这是我的 ListRowExtensions 扩展 hide 列表行分隔符和 custom 这个。
import SwiftUI
// MARK: List row extensions
extension View {
func hideListRowSeparator() -> some View {
return customListRowSeparator(insets: .init(), insetsColor: .clear)
}
func customListRowSeparator(
insets: EdgeInsets,
insetsColor: Color) -> some View {
modifier(HideRowSeparatorModifier(insets: insets,
background: insetsColor
)) .onAppear {
UITableView.appearance().separatorStyle = .none
UITableView.appearance().separatorColor = .clear
}
}
}
// MARK: ViewModifier
private struct HideRowSeparatorModifier: ViewModifier {
var insets: EdgeInsets
var background: Color
func body(content: Content) -> some View {
content
.padding(insets)
.frame(
minWidth: 0,
maxWidth: .infinity,
maxHeight: .infinity,
alignment: .leading
)
.listRowInsets(EdgeInsets())
.background(background)
}
}
使用:
// Without list row separator
List {
ForEach(self.viewModel.data, id: \.id) { item in
Text("Text")
}
.hideRowSeparatorItemList()
}
// With list row separator with color and size
List {
ForEach(self.viewModel.data, id: \.id) { item in
Text("Text")
}
.customListRowSeparator(insets: EdgeInsets(top: 0,
leading: 0,
bottom: 5,
trailing: 0),
insetsColor: Color.red)
}
我不确定您是否需要 SwiftUI 中“UITableView”的所有功能,但是如果您只想在 iOS 13 或更高版本中显示视图列表,您不能这样做:
ScrollView {
VStack(alignment: .leading) {
ForEach(1...10) { _ in
CustomRow()
}
}
}
然后添加 .padding()
以获得您想要的任何边距?
删除填充和分隔符
iOS14.2,Xcode12.2
ScrollView {
LazyVStack {
ForEach(viewModel.portfolios) { portfolio in
PortfolioRow(item: portfolio)
}
}
}
这使您可以完全控制列表。 List 的当前实现不提供完全控制并包含一些问题。
对于 iOS 14 你有这个:
.listStyle(SidebarListStyle()) # IOS 14
您可以通过将 listStyle 设置为 InsetListStyle()
来删除分隔符,如下所示:
.listStyle(InsetListStyle())
将此添加到代码的结尾
这似乎是唯一对我有用的东西。
List() {
}
.listStyle(SidebarListStyle())
适用于 iOS 13 和 14
的简单解决方案
extension List {
func removeSeparator() -> some View {
if #available(iOS 14.0, *) {
return self.listStyle(SidebarListStyle()).erasedToAnyView()
} else {
return self.onAppear {
UITableView.appearance().separatorStyle = .none
}.erasedToAnyView()
}
}
可以只使用负插图和纯色来遮盖分隔符。
我也遇到了同样的问题。但我知道一个手工制作的解决方案。因此,如果您将列表行参数设置为:
.listRowInsets(EdgeInsets(top: -5, leading: 0, bottom: 0, trailing: 0))
和行视图正文的填充如
.padding(EdgeInsets(top: Statics.adjustValue(v: 10), leading: Statics.adjustValue(v: 10), bottom: Statics.adjustValue(v: 10), trailing: Statics.adjustValue(v: 10)))
然后分隔符将被隐藏。
对于所有 iOS 个版本
对于iOS13,iOS14去掉第一个单元格顶部的分隔符
添加viewModifier
extension View {
func hideRowSeparator(insets: EdgeInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0),
background: Color = .white) -> some View {
modifier(HideRowSeparatorModifier(insets: insets, background: background))
}
}
struct HideRowSeparatorModifier: ViewModifier {
static let defaultListRowHeight: CGFloat = 44
var insets: EdgeInsets
var background: Color
init(insets: EdgeInsets, background: Color) {
self.insets = insets
var alpha: CGFloat = 0
if #available(iOS 14.0, *) {
UIColor(background).getWhite(nil, alpha: &alpha)
assert(alpha == 1, "Setting background to a non-opaque color will result in separators remaining visible.")
}
self.background = background
}
func body(content: Content) -> some View {
content
.padding(insets)
.frame(minWidth: 0, maxWidth: .infinity, minHeight: Self.defaultListRowHeight)
.listRowInsets(EdgeInsets())
.overlay(
VStack {
HStack {}
.frame(maxWidth: .infinity)
.frame(height: 1)
.background(background)
Spacer()
HStack {}
.frame(maxWidth: .infinity)
.frame(height: 1)
.background(background)
}
.padding(.top, -1)
)
}
}
用法
struct ContentView: View {
var body: some View {
List {
ForEach(0 ..< 30) { item in
HStack(alignment: .center, spacing: 30) {
Text("Hello, world!:\(item)").padding()
}
.hideRowSeparator(background: .white)
}
}
.listStyle(PlainListStyle())
}
}
对于iOS 14:
由于.listRowSeparator(.hidden)
仅适用于iOS 15,您可以通过显式将edgeinsets设置为0来隐藏低版本中的分隔符。
内容视图:
List {
ForEach(viewModel.items, id: \.id) { item in
YourListItem(item)
.listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
}
}
伴随上述变化,将行项目的背景设为白色(或根页面的颜色)
行项目:
var body: some View {
VStack {
..... your content
}
.background(Colors.white)
}
VStack 只是一个例子。它可以是任何组件。
这是我的解决方案,包含所有注意事项:
let style: UITableViewCell.SeparatorStyle
public func body(content: Content) -> some View {
content
.introspectTableView { tableView in
tableView.separatorStyle = .none
}
}
}
public extension View {
func listSeparator(style: UITableViewCell.SeparatorStyle) -> some View {
ModifiedContent(content: self, modifier: ListSeparatorStyle(style: style))
}
}
已实施:
List {
// code...
}
.listSeparator(style: .none)
要删除 SwiftUI 中的行分隔符,您可以通过附加 onAppear
修饰符来调整 List
视图,并调用 UITableView
的外观 API 来禁用行分隔符:
.onAppear {
UITableView.appearance().separatorStyle = .none
}
使用此代码,应删除列表视图的所有行分隔符。
我有显示自定义行列表的代码。
struct ContentView : View {
var body: some View {
VStack(alignment: .leading) {
List(1...10) {_ in
CustomRow()
}
}
}
}
但是,我想删除每一行上的线。我尝试不使用 List
而是在 ScrollView
中使用 ForEach
但它完全删除了所有样式,包括其填充和边距。我只想删除这些行,没有别的。
请帮忙,谢谢。
iOS 15+:
只需将 .listRowSeparator(.hidden)
作为修饰符添加到包含在 List
中的视图中。 https://developer.apple.com/documentation/swiftui/texteditor/listrowseparator(_:edges:)
List {
ForEach(garage.cars) { car in
Text(car.model)
.listRowSeparator(.hidden)
}
}
iOS 仅 13:
在 List
出现之前在代码中的任何位置添加 UITableView.appearance().separatorColor = .clear
应该可以。虽然此解决方案删除了分隔符,但请注意所有 List
实例都将绑定到此样式,因为目前没有官方方法只能删除特定实例的分隔符。您可以在 onAppear
中 运行 这段代码并在 onDisappear
中撤消它以保持样式不同。
另请注意,此代码假定 Apple 使用 UITableView
来支持 List
,这在 iOS 14 SDK 中并非如此。希望他们将来添加官方 API。感谢 https://twitter.com/singy/status/1169269782400647168.
iOS 15:
今年 Apple 推出了一个新修饰符 .listRowSeparator
,可用于设置分隔符的样式。你可以通过 .hidden
来隐藏它:
List {
ForEach(items, id:\.self) {
Text("Row \([=10=])")
.listRowSeparator(.hidden)
}
}
iOS 14:
您可以考虑在 ScrollView
中使用 LazyVStack
(因为 iOS 不 支持 SwiftUI 的 UIAppearance
不再列出)。
iOS 13:
⚠️ This method is deprecated and it's not working from iOS 14
在 SwiftUI 的 List
后面有一个 UITableView
用于 iOS 13。因此要删除
额外的分隔符(列表下方):
您需要 tableFooterView
并删除
所有分隔符(包括实际分隔符):
你需要 separatorStyle
才能成为 .none
用法示例
init() {
if #available(iOS 14.0, *) {
// iOS 14 doesn't have extra separators below the list by default.
} else {
// To remove only extra separators below the list:
UITableView.appearance().tableFooterView = UIView()
}
// To remove all separators including the actual ones:
UITableView.appearance().separatorStyle = .none
}
var body: some View {
List {
Text("Item 1")
Text("Item 2")
Text("Item 3")
}
}
请注意,默认情况下,静态列表不会在列表下方显示额外的分隔符
查看 SwiftUI-Introspect。它公开了底层的 UIKit/AppKit 视图。
iOS 仅 13 个版本:
在这种情况下,您可以直接操作 UITableView(无需通过外观代理更改所有 table 视图):
import Introspect
:
:
List {
...
}.introspectTableView { tableView in
tableView.separatorStyle = .none
}
做类似的事情:
UITableView.appearance().separatorColor = .clear
有效,但在很多情况下我不推荐这样做。这些是全局更改 - 即它们将影响 UITableView 的 all 个实例。如果您有多个需要不同样式的 UITableView,这就是一个问题。或者,如果您正在开发一个框架,那么使用您的框架的客户也会继承这些更改!
更安全的解决方案是仅针对位于指定容器内的 UITableView。幸运的是 appearance
api 给了我们一个具体的方法:
UITableView.appearance(whenContainedInInstancesOf: [UIHostingController<YourSwiftUiViewHere>.self]).separatorColor = .clear
使用 ScrollView?
代表您列表的某个州
@State var menuItems: [String] = ["One", "Two", "Three"]
SwiftUI
ForEach
循环 ScrollView
ScrollView {
ForEach(self.menuItems, id: \.self) { item in
Text(item)
}
}
iOS 仅 13 个版本:
虽然这些答案在技术上是正确的,但根据我的经验,它们会影响 List
或 Form
全局(在整个应用程序中)。
我发现至少在我的应用程序中解决此问题的一种 hacky 方法是将以下代码添加到应用程序的“主要”内容视图:
.onAppear(perform: {
UITableView.appearance().separatorStyle = .none
})
然后在您想要分隔线的任何其他视图上将其添加到 List
或 Form
视图的末尾
.onAppear(perform: {
UITableView.appearance().separatorStyle = .singleLine
})
这似乎将单行分隔符添加到主内容视图上方的任何视图 sheet。同样,这都是我最近的 SwiftUI 体验的轶事。
根据我的经验,我只需将 .onAppear(... = .singleLine)
方法添加到我的“详细信息”视图之一,分隔线就会出现在所有随后显示的视图中。
编辑: 另一个注意事项,因为这个答案继续受到关注。我 posted 的这个解决方案并没有解决所有情况,在某些情况下,它当然也没有为我解决。我最终使用 Introspect for SwiftUI 解决了整个应用程序中的这个问题。
我希望这能消除人们遇到此问题时的一些困惑和沮丧 post。
IOS 14
IOS 14 beta 目前没有隐藏分隔符的解决方案。
如果您不需要可编辑的 List
,您应该在 ScrollView
中使用 LazyVStack
。
但是如果你想留在List
。我在 samwarner 的 Apple 论坛上找到了解决方案。 https://developer.apple.com/forums/thread/651028
这是一个临时解决方案。在某些情况下,您可能需要调整插图。 这是它的实现:
struct HideRowSeparatorModifier: ViewModifier {
static let defaultListRowHeight: CGFloat = 44
var insets: EdgeInsets
var background: Color
init(insets: EdgeInsets, background: Color) {
self.insets = insets
var alpha: CGFloat = 0
UIColor(background).getWhite(nil, alpha: &alpha)
assert(alpha == 1, "Setting background to a non-opaque color will result in separators remaining visible.")
self.background = background
}
func body(content: Content) -> some View {
content
.padding(insets)
.frame(
minWidth: 0, maxWidth: .infinity,
minHeight: Self.defaultListRowHeight,
alignment: .leading
)
.listRowInsets(EdgeInsets())
.background(background)
}
}
extension EdgeInsets {
static let defaultListRowInsets = Self(top: 0, leading: 16, bottom: 0, trailing: 16)
}
extension View {
func hideRowSeparator(insets: EdgeInsets = .defaultListRowInsets, background: Color = .white) -> some View {
modifier(HideRowSeparatorModifier(insets: insets, background: background))
}
}
最后,这里是列表中的实现。您必须在列表单元格中添加 .hideRowSeparator()
。
struct CustomRow: View {
let text: String
var body: some View {
HStack {
Text(self.text)
Image(systemName: "star")
}
}
}
struct ContentView : View {
@State private var fruits = ["Apple", "Orange", "Pear", "Lemon"]
var body: some View {
VStack(alignment: .leading) {
List {
ForEach(self.fruits, id: \.self) { str in
CustomRow(text: str)
.hideRowSeparator()
}
}
}
.padding(.top)
}
}
我在 iOS14 开始了一个项目来解决这个问题,因为 iOS 13 变通办法不再有效。它允许设置分隔符样式、分隔符颜色和分隔符插入。
隐藏列表中的分隔符
List { <content> }
.listSeparatorStyle(.none)
显示带有可配置颜色和插图的单个分隔线
List { <content> }
.listSeparatorStyle(.singleLine, color: .red, inset: EdgeInsets(top: 0, leading: 50, bottom: 0, trailing: 20)
所有答案都告诉你使用ScrollView(这也是我推荐的)
但如果您想使用 List 并希望删除分隔线..
安装 SwiftPM:https://github.com/siteline/SwiftUI-Introspect
样本:
List {
Text("Item 1")
Text("Item 2")
}
.introspectTableView { tableView in
tableView.separatorStyle = .none
}
这是我的 ListRowExtensions 扩展 hide 列表行分隔符和 custom 这个。
import SwiftUI
// MARK: List row extensions
extension View {
func hideListRowSeparator() -> some View {
return customListRowSeparator(insets: .init(), insetsColor: .clear)
}
func customListRowSeparator(
insets: EdgeInsets,
insetsColor: Color) -> some View {
modifier(HideRowSeparatorModifier(insets: insets,
background: insetsColor
)) .onAppear {
UITableView.appearance().separatorStyle = .none
UITableView.appearance().separatorColor = .clear
}
}
}
// MARK: ViewModifier
private struct HideRowSeparatorModifier: ViewModifier {
var insets: EdgeInsets
var background: Color
func body(content: Content) -> some View {
content
.padding(insets)
.frame(
minWidth: 0,
maxWidth: .infinity,
maxHeight: .infinity,
alignment: .leading
)
.listRowInsets(EdgeInsets())
.background(background)
}
}
使用:
// Without list row separator
List {
ForEach(self.viewModel.data, id: \.id) { item in
Text("Text")
}
.hideRowSeparatorItemList()
}
// With list row separator with color and size
List {
ForEach(self.viewModel.data, id: \.id) { item in
Text("Text")
}
.customListRowSeparator(insets: EdgeInsets(top: 0,
leading: 0,
bottom: 5,
trailing: 0),
insetsColor: Color.red)
}
我不确定您是否需要 SwiftUI 中“UITableView”的所有功能,但是如果您只想在 iOS 13 或更高版本中显示视图列表,您不能这样做:
ScrollView {
VStack(alignment: .leading) {
ForEach(1...10) { _ in
CustomRow()
}
}
}
然后添加 .padding()
以获得您想要的任何边距?
删除填充和分隔符
iOS14.2,Xcode12.2
ScrollView {
LazyVStack {
ForEach(viewModel.portfolios) { portfolio in
PortfolioRow(item: portfolio)
}
}
}
这使您可以完全控制列表。 List 的当前实现不提供完全控制并包含一些问题。
对于 iOS 14 你有这个:
.listStyle(SidebarListStyle()) # IOS 14
您可以通过将 listStyle 设置为 InsetListStyle()
来删除分隔符,如下所示:
.listStyle(InsetListStyle())
将此添加到代码的结尾
这似乎是唯一对我有用的东西。
List() {
}
.listStyle(SidebarListStyle())
适用于 iOS 13 和 14
的简单解决方案extension List {
func removeSeparator() -> some View {
if #available(iOS 14.0, *) {
return self.listStyle(SidebarListStyle()).erasedToAnyView()
} else {
return self.onAppear {
UITableView.appearance().separatorStyle = .none
}.erasedToAnyView()
}
}
可以只使用负插图和纯色来遮盖分隔符。
我也遇到了同样的问题。但我知道一个手工制作的解决方案。因此,如果您将列表行参数设置为:
.listRowInsets(EdgeInsets(top: -5, leading: 0, bottom: 0, trailing: 0))
和行视图正文的填充如
.padding(EdgeInsets(top: Statics.adjustValue(v: 10), leading: Statics.adjustValue(v: 10), bottom: Statics.adjustValue(v: 10), trailing: Statics.adjustValue(v: 10)))
然后分隔符将被隐藏。
对于所有 iOS 个版本
对于iOS13,iOS14去掉第一个单元格顶部的分隔符
添加viewModifier
extension View {
func hideRowSeparator(insets: EdgeInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0),
background: Color = .white) -> some View {
modifier(HideRowSeparatorModifier(insets: insets, background: background))
}
}
struct HideRowSeparatorModifier: ViewModifier {
static let defaultListRowHeight: CGFloat = 44
var insets: EdgeInsets
var background: Color
init(insets: EdgeInsets, background: Color) {
self.insets = insets
var alpha: CGFloat = 0
if #available(iOS 14.0, *) {
UIColor(background).getWhite(nil, alpha: &alpha)
assert(alpha == 1, "Setting background to a non-opaque color will result in separators remaining visible.")
}
self.background = background
}
func body(content: Content) -> some View {
content
.padding(insets)
.frame(minWidth: 0, maxWidth: .infinity, minHeight: Self.defaultListRowHeight)
.listRowInsets(EdgeInsets())
.overlay(
VStack {
HStack {}
.frame(maxWidth: .infinity)
.frame(height: 1)
.background(background)
Spacer()
HStack {}
.frame(maxWidth: .infinity)
.frame(height: 1)
.background(background)
}
.padding(.top, -1)
)
}
}
用法
struct ContentView: View {
var body: some View {
List {
ForEach(0 ..< 30) { item in
HStack(alignment: .center, spacing: 30) {
Text("Hello, world!:\(item)").padding()
}
.hideRowSeparator(background: .white)
}
}
.listStyle(PlainListStyle())
}
}
对于iOS 14:
由于.listRowSeparator(.hidden)
仅适用于iOS 15,您可以通过显式将edgeinsets设置为0来隐藏低版本中的分隔符。
内容视图:
List {
ForEach(viewModel.items, id: \.id) { item in
YourListItem(item)
.listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
}
}
伴随上述变化,将行项目的背景设为白色(或根页面的颜色)
行项目:
var body: some View {
VStack {
..... your content
}
.background(Colors.white)
}
VStack 只是一个例子。它可以是任何组件。
这是我的解决方案,包含所有注意事项:
let style: UITableViewCell.SeparatorStyle
public func body(content: Content) -> some View {
content
.introspectTableView { tableView in
tableView.separatorStyle = .none
}
}
}
public extension View {
func listSeparator(style: UITableViewCell.SeparatorStyle) -> some View {
ModifiedContent(content: self, modifier: ListSeparatorStyle(style: style))
}
}
已实施:
List {
// code...
}
.listSeparator(style: .none)
要删除 SwiftUI 中的行分隔符,您可以通过附加 onAppear
修饰符来调整 List
视图,并调用 UITableView
的外观 API 来禁用行分隔符:
.onAppear {
UITableView.appearance().separatorStyle = .none
}
使用此代码,应删除列表视图的所有行分隔符。