我有这段代码来显示自定义行的列表。
struct ContentView : View {
var body: some View {
VStack(alignment: .leading) {
List(1...10) {_ in
CustomRow()
}
}
}
}
但是,我想删除每一行上的行。我尝试不使用List
,而是在ForEach
内使用ScrollView
,但是它完全删除了所有样式,包括其填充和边距。我只想删除这些行而已。
请帮助,谢谢。
答案 0 :(得分:26)
在UITableView.appearance().separatorColor = .clear
出现之前在代码中的任何位置添加List
应该可以。尽管此解决方案删除了分隔符,但请注意,所有List
实例都将绑定到该样式,因为目前尚无官方方法只能删除特定实例的分隔符。您可以在onAppear
中运行此代码,并在onDisappear
中撤消该代码,以保持样式的不同。另请注意,此代码假定Apple使用UITableView
来备份List
,但这可能并非永远如此。希望他们将来会添加正式的API。
答案 1 :(得分:15)
iOS的SwiftUI的UITableView
后面有一个List
。因此,删除
您需要一个tableFooterView
并删除
您需要separatorStyle
才能成为.none
init() {
// 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")
}
}
答案 2 :(得分:10)
签出SwiftUI-Introspect。它公开了底层的 UIKit / AppKit 视图。
在这种情况下,您可以直接操作UITableView(而不必通过外观代理更改所有表视图):
import Introspect
:
:
List {
...
}.introspectTableView { tableView in
tableView.separatorStyle = .none
}
答案 3 :(得分:6)
对于 iOS 14,你有这个:
.listStyle(SidebarListStyle()) # IOS 14
答案 4 :(得分:5)
尽管这些答案在技术上都是正确的,但根据我的经验,它们会在全球范围内(整个应用程序中)影响List
或Form
。
至少在我的应用程序中,我发现一种解决该问题的方法,是将以下代码添加到该应用程序的“主要”内容视图中:
.onAppear(perform: {
UITableView.appearance().separatorStyle = .none
})
然后在您要使用分隔线的任何其他视图上,将其添加到List
或Form
视图的末尾
.onAppear(perform: {
UITableView.appearance().separatorStyle = .singleLine
})
这似乎将单行分隔符添加到主内容视图上方的任何视图表中。同样,这都是我最近的SwiftUI经验的轶事。
根据我的经验,我只需要在我的一个“详细”视图中添加.onAppear(... = .singleLine)
方法,并且在随后显示的所有视图中都显示分隔线。
编辑:由于该答案继续引起人们的注意,请注意另一点。我发布的这个解决方案并不能解决所有情况,当然在某些情况下也不能解决我的问题。我最终使用Introspect for SwiftUI来解决整个应用程序中的问题。
我希望当人们看到这篇文章时,这能消除一些困惑和沮丧。
答案 5 :(得分:4)
做类似的事情:
UITableView.appearance().separatorColor = .clear
有效,但是在很多情况下我不建议这样做。这些是全局更改-即它们将影响UITableView的所有实例。如果您有多个需要不同样式的UITableView,这将是一个问题。或者,如果您正在开发框架,则使用您的框架的客户也将继承这些更改!
一个更安全的解决方案是仅定位位于指定容器内的UITableViews。幸运的是,appearance
API为我们提供了一种具体的方法:
UITableView.appearance(whenContainedInInstancesOf: [UIHostingController<YourSwiftUiViewHere>.self]).separatorColor = .clear
答案 6 :(得分:3)
我从上述答案中得到了提示。谢谢。 我的解决办法是这个。
init() {
UITableView.appearance().tableFooterView = UIView()
}
var body: some View {
List {
...
}
}
答案 7 :(得分:3)
IOS 14
当前没有解决方案可以在IOS 14 beta上隐藏分隔符。
如果您不需要可编辑的List
,则应在LazyVStack
内使用ScrollView
。
但是,如果您想停留在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)
}
}
答案 8 :(得分:3)
删除填充和分隔符
iOS 14.2、Xcode 12.2
ScrollView {
LazyVStack {
ForEach(viewModel.portfolios) { portfolio in
PortfolioRow(item: portfolio)
}
}
}
这使您可以完全控制列表。 List 的当前实现不提供完全控制并包含一些问题。
答案 9 :(得分:2)
这似乎是唯一对我有用的东西。
List() {
}
.listStyle(SidebarListStyle())
答案 10 :(得分:2)
使用ScrollView吗?
代表您的列表的某些状态
@State var menuItems: [String] = ["One", "Two", "Three"]
SwiftUI
内的ForEach
ScrollView
循环
ScrollView {
ForEach(self.menuItems, id: \.self) { item in
Text(item)
}
}
答案 11 :(得分:2)
我开始在iOS14中解决此问题的项目,因为iOS 13变通办法不再起作用。它允许设置分隔符样式,分隔符颜色和分隔符插图。
隐藏列表中的分隔符
List { <content> }
.listSeparatorStyle(.none)
显示一条带有可配置颜色和插图的分隔线
List { <content> }
.listSeparatorStyle(.singleLine, color: .red, inset: EdgeInsets(top: 0, leading: 50, bottom: 0, trailing: 20)
答案 12 :(得分:1)
所有答案都告诉您使用ScrollView(这也是我的建议)
但是如果您要使用列表并要删除分隔线。.
安装SwiftPM:https://github.com/siteline/SwiftUI-Introspect
示例:
List {
Text("Item 1")
Text("Item 2")
}
.introspectTableView { tableView in
tableView.separatorStyle = .none
}
答案 13 :(得分:0)
我不确定您是否需要SwiftUI中“ UITableView”的所有功能,但是如果您只想在iOS 13或更高版本中显示视图列表,就不能这样做:
ScrollView {
VStack(alignment: .leading) {
ForEach(1...10) { _ in
CustomRow()
}
}
}
然后添加.padding()
以获得所需的边距吗?
答案 14 :(得分:0)
这是我的扩展名 ListRowExtensions ,用于隐藏列表行分隔符和自定义。
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)
}
答案 15 :(得分:0)
除了@Mojtaba Hosseini答案外,这是您如何隐藏列表包括最后一个以下的额外分隔符的方法:
init() {
UITableView.appearance().tableFooterView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: 1))
}
答案 16 :(得分:0)
您可以通过将 listStyle 设置为 InsetListStyle()
来删除分隔符,如下所示:
.listStyle(InsetListStyle())
将此添加到代码的结尾
答案 17 :(得分:0)
尝试插入.listRowInsets(EdgeInsets(top:5,前导:5,bottom:5,尾随:5))为行添加填充,您可以在VSTack中对其进行样式设置。
struct ContentView : View {
var body: some View {
VStack(alignment: .leading) {
List(1...10) {_ in
CustomRow()
}
}
.listRowInsets(EdgeInsets(top: 5, leading: 5, bottom: 5, trailing: 5))
}
}
第二种方法是:(另外,如果需要传递Binding,则可以在下面看到,如果不忽略enableNext传递的值)。
struct ContentView : View {
@State var enableNextState: Bool = false
var body: some View {
VStack(alignment: .leading) {
List(1...10) {_ in
CustomRow(enableNext: enableNextState )
}
}
}
}
struct CustomRow: View {
@Binding var enableNext: Bool
init(enableNext: Binding<Bool>) {
self._enableNext = enableNext
UITableView.appearance().separatorColor = .clear
}
var body: some View {
Text("ROW DATA")
}
}
答案 18 :(得分:0)
可以只使用负插图和纯色来掩盖分隔符。
答案 19 :(得分:0)
我也有同样的问题。但我知道一个手工制作的解决方案。因此,如果您将 List 行参数设置为:
.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 版本
答案 20 :(得分:0)
extension View {
/// 隐藏 List 中的 分割线
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())
}
}
答案 21 :(得分:0)
对于 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 只是一个例子。它可以是任何组件。
答案 22 :(得分:-1)
适用于 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()
}
}