【问题标题】:Best way to add multiple diagonal connection lines between TableViewCells在表格视图单元格之间添加多条对角线连接线的最佳方法
【发布时间】:2017-08-21 10:18:48
【问题描述】:

我正在创建一个需要显示如下图的 tableview 的应用程序

相似颜色的圆圈要匹配一条线。

我可以在哪个视图中添加线条? 还是需要在tableview之上新建一个view?但是我的 tableview 仍然需要滚动。

我怎样才能做到这一点?

赏金更新

我想用相邻圆圈之间的倾斜线来实现相同的功能。如何达到同样的效果?

下面的演示:

【问题讨论】:

  • 一种可行的方法是将自定义UIViews 添加到您的UITableViewCell 子类中,代表一半的行。当你想在两个单元格之间画一条线时,你只需从上面的单元格画出一半的线,从下面的单元格画出另一半。
  • “倾斜”是指对角线吗?所以你想让一个圆圈能够连接到正上方/下方的圆圈,加上 4 个相邻的对角线?
  • 是的,取决于来自服务器的数据.. 我需要对角连接
  • @PeterParker 添加了有问题的更新图像。
  • @Saranjith 啊,我明白了????添加了支持任何对角线连接的答案。

标签: ios uitableview core-graphics


【解决方案1】:

创建这样的设计

根据您的要求,只需隐藏圆圈的上线和下线

【讨论】:

  • 这是最聪明的答案:不需要将无关的子视图直接添加到表格视图中(在滚动/重用单元格时管理起来很麻烦)。但是,您的行不能跨越由表格分隔符创建的间隙。一种解决方法是禁用表格视图上的分隔符(设置为.none),并在每个单元格中使用 0.5pt 高的子视图伪造它。只要确保假细胞分隔符位于所有垂直连接线的下方
  • 这是一个很好的答案,但似乎对所有布局都不灵活。像 iPad 和 iPhone 的
  • 但是怎么做呢?线是uiview,你只需给出它的宽度和颜色我认为它适用于所有设备@Saranjith
  • 但在 ipad 中,单元格右侧会有多余的空间。应该是横向模式。如果核心图形可以提供帮助,那就太好了
  • 最好以编程方式创建它,如果您打算使用动画,请使用 CAShapeLayer。
【解决方案2】:

您需要在 tableview 单元格中创建集合视图。在集合视图中,您创建一个单元格。设计与您的设计相同的用户界面。显示和隐藏规则匹配的视图。它不会影响 tableview 滚动。通过这种方法,您还可以在集合视图单元格中提供滚动。如果您能够向我提供更多信息,我可以为您提供编码解决方案。谢谢

你可以用这个Third Party LIb

【讨论】:

  • 那我怎样才能连接圈子呢?
  • 使用collectionview的水平滚动可以匹配圆形。
  • 听起来有点矫枉过正?
【解决方案3】:

您需要结合使用集合视图和表格视图来支持所有设备。

1.创建一个collection view cell,布局如下

  1. 根据需要隐藏上下线

  2. 在表格视图单元格中添加集合视图,并根据当前设备宽度和项目之间的间距管理集合视图中的多个单元格。

【讨论】:

  • 如果在collectionview中启用了滚动,那么整个概念就会正确
【解决方案4】:

您可以创建一个不带文本的垂直标签,将背景颜色设置为黑色,并将其放置在视图层次结构中的圆圈后面,并根据您的要求设置标签的宽度。然后您可以随时隐藏取消隐藏标签。

P.S.:确保隐藏单元格分隔符。

我创建了一个演示项目。 You can find it here. 我试图满足您的要求。您可以更新集合视图设置以处理标签的隐藏和显示。

如果您有任何问题,请告诉我。

希望对您有所帮助。 谢谢!

【讨论】:

    【解决方案5】:

    要将任何圆圈与上方/下方单元格中的任何其他圆圈连接起来,动态创建连接线会更容易和更清晰,而不是像以前那样将它们构建到资产中。这部分很简单。现在的问题是在哪里添加它们。

    您可以将每两个单元格之间的连接线包含在每对单元格的顶部或底部单元格中,因为视图可以显示超出其边界的内容。

    这有一个问题,不管哪个单元格包含这些行。例如,如果顶部单元格包含它们,那么一旦它向上滚动到屏幕之外,当调用 didEndDisplayingCell 时,这些行就会消失,即使底部单元格仍然完全在屏幕上。然后稍微滚动一下,调用 cellForRow,这些线条会突然再次出现。

    如果你想避免这个问题,那么这里有一种方法:

    一种方法

    为您的表格视图和单元格提供清晰的背景颜色,并在下面有另一个表格视图以显示一个包含连接线的新单元格。

    所以你现在有一个背景 TVC 和一个后单元格,以及一个前景 TVC 和一个前单元格。您将这些 TVC 作为子级添加到父视图控制器中(您可以在其中设置您喜欢的任何背景颜色),禁用背景 TVC 上的用户交互,并将背景 TVC 的内容偏移量与观察块中前景 TVC 的内容偏移量挂钩,所以它们在滚动时会保持同步。我以前做过这个;它运作良好。使用相同的行高,并将背景 TVC 的顶部插入设置为行高的一半。

    我们可以使背面单元格中的连接线紧贴单元格的顶部和底部边缘。这样,圆圈将在其中心连接。

    也许在你的模型中定义一个方法来计算有哪些连接,并返回它们,这是模型的关注点。

    extension Array where Element == MyModel {
    
        /**
        A connection is a (Int, Int).
        (0, 0) means the 0th circle in element i is connected to the 0th circle in element j
        For each pair of elements i, j, there is an array of such connections, called a mesh.
        Returns n - 1 meshes.
        */
        func getMeshes() -> [[(Int, Int)]] {
            // Your code here
        }
    }
    

    然后在你的父 VC 中,做这样的事情:

    class Parent_VC: UIViewController {
    
        var observation: NSKeyValueObservation!
        var b: Background_TVC!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let b = Background_TVC(model.getMeshes())
            let f = Foreground_TVC(model)
    
            for each in [b, f] {
                self.addChild(each)
                each.view.frame = self.view.bounds
                self.view.addSubview(each.view)
                each.didMove(toParent: self)
            }
    
            let insets = UIEdgeInsets(top: b.tableView.rowHeight / 2, left: 0, bottom: 0, right: 0)
            b.tableView.isUserInteractionEnabled = false
            b.tableView.contentInset = insets
            self.b = b
    
            self.observation = f.tableView.observe(\.contentOffset, options: [.new]) { (_, change) in
                let y = change.newValue!.y
                self.b.tableView.contentOffset.y = y // + or - half the row height
            }
        }
    }
    

    当然还有你的绘图代码。您可以将其设为您的后台单元类(自定义单元)的方法,该方法将采用网格数据结构,然后绘制代表它的线条。像这样的:

    class Back_Cell: UITableViewCell {
    
        /**
         Returns an image with all the connection lines drawn for the given mesh.
         */
        func createMeshImage(for mesh: [(Int, Int)]) -> UIImage {
            let canvasSize = self.contentView.bounds.size
    
            // Create a new canvas
            UIGraphicsBeginImageContextWithOptions(canvasSize, false, 0)
    
            // Grab that canvas
            let canvas = UIGraphicsGetCurrentContext()!
    
            let spacing: CGFloat = 10.0 // whatever the spacing between your circles is
    
            // Draw the lines
            for each in mesh {
                canvas.move(to: CGPoint(x: CGFloat(each.0) * spacing, y: 0))
                canvas.addLine(to: CGPoint(x: CGFloat(each.1) * spacing, y: self.contentView.bounds.height))
            }
    
            canvas.setStrokeColor(UIColor.black.cgColor)
            canvas.setLineWidth(3)
            canvas.strokePath()
    
            let image = UIGraphicsGetImageFromCurrentImageContext()!
            UIGraphicsEndImageContext()
            return image
        }
    }
    

    您可能希望创建一个 Mesh 类并将图像存储在该模型中,以避免重绘。

    【讨论】:

      猜你喜欢
      • 2021-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-12
      • 1970-01-01
      • 1970-01-01
      • 2011-08-16
      相关资源
      最近更新 更多