IOS - 如何创建带有水平滚动列表的 TableView

IOS - How to create TableView with horizontal scrollable lists

我正在尝试实现一个 table 视图,其中包含可滚动的水平项目(项目数量未知),如下图所示:

UI 应该像这样:

  1. 在初始状态下,table 单元格显示一个标签和一些文本,并且圆形项从右侧弹出
  2. 如果用户从右向左滑动,标签和文本会淡出,水平列表(在单元格内)取而代之

我考虑过使用 TableView 和 dequeueReusableCellWithIdentifier 并创建一个原型单元格,但随后我需要记住列表的水平位置并在 cellForRowAtIndexPath 上正确初始化单元格,这可能会影响性能。

问:为了实现这个目标你会使用什么布局,任何输入/教程将不胜感激

您可以使用 ScrollView 将其放入您的表格视图中,并将滚动视图的值 "Direction lock enabled" 和 "Paging Enabled" 设置为 true。

如果每个滚动视图中有大量 UI 元素,使用 UIScrollView 可能需要付出很大的努力,因为您必须预先实例化所有这些元素。更好的解决方案是定义您的自定义 UITableViewCell,它有自己的 UITableView 但旋转 90 度以进行水平滚动。 UI里面的元素只有在需要使用dequeueReusableCellWithIdentifier:forIndexPath:显示的时候才会被创建。请查看一些关于如何创建 90 度旋转 table 视图的示例代码:

iPhone Tableview Use Cells in Horizontal Scrolling not Vertical

使用 UITableView 并向可重复使用的 tableView 单元格添加 UICollectionViewUICollectionViewUITableView 的工作方式类似,因为 "items"(如单元格)是可重复使用的,并且只有在它们出现在屏幕上时才会实例化。我快速 google 搜索教程并找到 UICollectionView in UITableViewCell。检查一下以及其他一些关于设计的 Whosebug 问题,你应该是金子。

- SwiftUI

在 swiftUI 中,您可以使用 Stacks 和 ScrollView 的强大功能以及 List(如果需要):

struct ContentView: View {

    var verticalData = 0...3
    var horizontalData = 0...15

    var body: some View {
        List(self.verticalData, id: \.self) { vData in
            ScrollView(.horizontal) {
                HStack(spacing: 16) {
                    ForEach(self.horizontalData, id: \.self) { _ in
                        Circle()
                            .foregroundColor(.blue)
                            .frame(width: 40, height: 40, alignment: .center)
                    }
                }
            }
        }
    }
}

在此示例中,我使用 List 表示垂直数据,使用水平 ScrollView 包含 HStack(水平堆栈)圆。

- 例子

以下代码是唯一可以重现与您的插图完全相同的视图的代码(4 年后 iPhone Xs):

struct CircleView: View {
    var body: some View {
        Circle()
        .foregroundColor(.blue)
        .frame(width: 80, height: 80, alignment: .center)
    }
}

struct RowView: View {
    var body: some View {
        ScrollView(.horizontal) {
            HStack(spacing: 16) {
                VStack(alignment: .leading, spacing: 4) {
                    Text("Label")
                    Text("Some text here")
                }
                ForEach(0...15, id: \.self) { _ in
                    CircleView()
                }
            }
            .padding(16)
        }
    }
}

struct ContentView: View {

    var body: some View {
        List {
            ForEach(0...3, id: \.self) { _ in
                RowView()
            }.listRowInsets(EdgeInsets())
        }
    }
}

- 结果