要将任何圆圈与上方/下方单元格中的任何其他圆圈连接起来,动态创建连接线会更容易和更清晰,而不是像以前那样将它们构建到资产中。这部分很简单。现在的问题是在哪里添加它们。
您可以将每两个单元格之间的连接线包含在每对单元格的顶部或底部单元格中,因为视图可以显示超出其边界的内容。
这有一个问题,不管哪个单元格包含这些行。例如,如果顶部单元格包含它们,那么一旦它向上滚动到屏幕之外,当调用 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 类并将图像存储在该模型中,以避免重绘。