如何在不使用ForEach的情况下从SwiftUI中的列表中删除行分隔符?

gre*_*rey 19 swift swiftui

我有这段代码来显示自定义行的列表。

struct ContentView : View {
    var body: some View {
        VStack(alignment: .leading) {
            List(1...10) {_ in
                CustomRow()
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,我想删除每一行上的行。我尝试不使用List,而是使用ForEachinside,ScrollView但是它完全删除了所有样式,包括其填充和边距。我只想删除行,仅此而已。

请帮忙,谢谢。

Nat*_*nel 25

UITableView.appearance().separatorColor = .clearList出现之前在代码中添加任何位置都可以。尽管此解决方案删除了​​分隔符,但请注意,所有List实例都将绑定到该样式,因为目前尚无官方方法只能删除特定实例的分隔符。您可能可以在其中运行此代码,onAppear然后将其撤消onDisappear以保持样式不同。另请注意,此代码假定Apple使用a UITableView作为后盾List,但可能永远不会正确。希望他们将来会添加正式的API。

  • 谢谢!请注意,我将修改分隔符样式,因为它更容易恢复到初始状态`.onAppear {UITableView.appearance()。separatorStyle = .none} .onDisappear {UITableView.appearance()。separatorStyle = .singleLine} ` (6认同)

Moj*_*ini 10

iOS的UITableViewSwiftUI背后有一个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")
    }
}
Run Code Online (Sandbox Code Playgroud)

  • `UITableView.appearance().separatorStyle = .none` 奇怪地对我不起作用,也不是 `.introspectTableView { tableView in tableView.separatorStyle = .none }` (使用 `SwiftUI-Introspect`...) (8认同)
  • 谢谢,这有效,您也可以将其添加到``.onAppear`` (7认同)
  • 请注意,确保“.listRowSeparator(.hidden)”位于“List”内部非常重要。 (5认同)

mar*_*kiv 10

查看SwiftUI-Introspect。它公开了底层的UIKit/AppKit视图。

仅 iOS 13 构建:

在这种情况下,您可以直接操作 UITableView(无需通过外观代理更改所有表视图):

    import Introspect
    :
    :
    List {
        ...
    }.introspectTableView { tableView in
         tableView.separatorStyle = .none
    }
Run Code Online (Sandbox Code Playgroud)

  • 是的,这不再适用于 iOS 14 版本。根据您的用例,您可以尝试“SidebarListStyle”来隐藏分隔符:“.listStyle(SidebarListStyle())” (2认同)

glo*_*lob 8

仅 iOS 13 构建:

虽然这些答案是技术上是正确的,他们会影响ListForm从我的经验,在全球(整个应用程序)。

我发现至少在我的应用程序中解决此问题的一种黑客方法是将以下代码添加到应用程序的“主”内容视图中:

.onAppear(perform: {
    UITableView.appearance().separatorStyle = .none
})
Run Code Online (Sandbox Code Playgroud)

然后在您想要分隔线的任何其他视图上将此添加到ListForm视图的末尾

.onAppear(perform: {
    UITableView.appearance().separatorStyle = .singleLine
})
Run Code Online (Sandbox Code Playgroud)

这似乎将单行分隔符添加到主内容视图上方的任何视图表。这也是我最近的 SwiftUI 体验的轶事。

根据我的经验,我只需要将.onAppear(... = .singleLine)方法添加到我的“详细信息”视图之一,分隔线就会出现在所有后续显示的视图中。

编辑:另一个说明,因为这个答案继续受到关注。我发布的这个解决方案并没有解决所有情况,它肯定没有为我解决,在某些情况下也是如此。我最终使用Introspect for SwiftUI来解决整个应用程序中的这个问题。

我希望这能消除人们看到这篇文章时的一些困惑和沮丧。


Ato*_*xic 8

IOS 14

在此处输入图片说明

目前没有在 IOS 14 测试版上隐藏分隔符的解决方案。

如果您不需要可编辑的List,则应该LazyVStackScrollView.

但如果你想留在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))
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,这是列表中的实现。您必须添加.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)
    }
}
Run Code Online (Sandbox Code Playgroud)


Yan*_*eph 7

对于 iOS 14,你有这个:

.listStyle(SidebarListStyle()) # IOS 14
Run Code Online (Sandbox Code Playgroud)

  • 感谢您指出这一点。它删除了分隔符和公开箭头,但现在它添加了一个我无法删除的灰色背景。有没有办法改变背景?苹果为什么要把事情搞得这么复杂? (7认同)

tom*_*lly 5

做类似的事情:

UITableView.appearance().separatorColor = .clear
Run Code Online (Sandbox Code Playgroud)

有效,但在很多情况下不是我推荐的。这些是全局更改 - 即它们将影响UITableView 的所有实例。如果您有多个需要不同样式的 UITableView,这是一个问题。或者,如果您正在开发一个框架,使用您的框架的客户端也将继承这些更改!

更安全的解决方案是仅针对位于指定容器内的 UITableViews。幸运的是,appearanceapi 为我们提供了一种具体的方法:

UITableView.appearance(whenContainedInInstancesOf: [UIHostingController<YourSwiftUiViewHere>.self]).separatorColor = .clear
Run Code Online (Sandbox Code Playgroud)

  • 首先,您的代码甚至无法编译,因为正确的名称是“appearance(whenContainedInInstancesOf:)”。但总的来说,这听起来确实是一种更好的方法。可悲的是,它对我不起作用。我用目标覆盖替换了全局外观覆盖(按预期工作),但它没有任何效果...... (2认同)