在TableViewCells之间添加多个连接线的最佳方法

时间:2017-08-21 10:18:48

标签: ios uitableview core-graphics

我正在创建一个需要显示如下图像的桌面视图的应用 enter image description here

类似的彩色圆圈与一条线匹配。

我可以添加哪些视图? 或者需要在tableview上面创建一个新视图?但我的桌面视图仍然需要滚动。

我怎样才能做到这一点?

5 个答案:

答案 0 :(得分:12)

像这样创建设计

enter image description here

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

答案 1 :(得分:3)

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

您可以使用此Third Party LIb

答案 2 :(得分:2)

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

1.使用以下布局创建一个集合视图单元格

Custome Collection view cell

  1. 根据需要隐藏上下行

  2. 在表格视图单元格中添加集合视图,并在集合视图中管理多个单元格,具体取决于当前设备宽度和项目间距。

答案 3 :(得分:1)

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

P.S。:确保隐藏细胞分离器。

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

如果您有任何问题,请与我们联系。

希望这有帮助。 谢谢!

答案 4 :(得分:0)

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

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

这是有问题的,无论哪个单元格包含行。例如,如果顶部单元格包含这些单元格,则在屏幕上向上滚动时,即使底部单元格仍完全显示在屏幕上,当调用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类并将图像存储在该模型中,以避免重绘。