请注意单词" graph"这里的意思是图论图,而不是统计图。
我正在尝试创建一个包含节点的图表,您可以在屏幕上移动它们。我决定使用自定义UIView
子类 - NodeView
来表示节点。为了使它可移动,我使用了CocoaPod SEDraggable。
我决定整个图表将由另一个名为UIView
的自定义GraphView
绘制。此类具有graph
属性,在设置时,它将首先从上一个图形中移除子视图(如果有)然后添加新的NodeView
来绘制整个图形。然后我会拨打setNeedsDisplay
,然后拨打draw(_:)
。
在重写的draw
方法中,我将在节点之间绘制线条(边缘,用图表理论术语)。
现在我需要检测一个节点是否已被移动。当它们被移动时,我需要调用setNeedsDisplay
来重绘线条。我环顾四周,明白这可以用KVO完成。但是,我的图表视图需要能够显示具有任意数量节点的图形。这意味着我将把我的节点放入一个数组中。根据这个post,KVOing数组是不可能的。
然后我尝试使用NSNotificationCenter
但我很快发现没有关于何时从post移动视图的通知。
然后我发现了这个post,但OP使用KVO,由于上述原因,我不能使用KVO。此外,该帖子在Objective-C中,我无法理解。
如何创建这样的图形?我正朝着正确的方向前进吗?或者是否有一个我可以使用的技巧,不涉及在移动节点时重绘所有内容?我觉得重新绘制整个图表的每一帧都会很慢。
答案 0 :(得分:0)
我发现我可以使用CADisplayLink
执行此操作。 <{1}}移动时,我不是重新绘制线条,而是每帧重绘一次。
NodeView
// displayLink is a property of the GraphView class
displayLink = CADisplayLink(target: self, selector: #selector(updateNodePositions))
displayLink.add(to: .main, forMode: .defaultRunLoopMode)
// ...
@objc func updateNodePositions() {
// nodeViewsToNodes is a dictionary storing all the NodeViews as keys
// and the corresponding Node (my model object) as values. So here
// I am basically updating the model based on the view's positions
for kvp in nodeViewsToNodes {
kvp.value.x = kvp.key.frame.midX
kvp.value.y = kvp.key.frame.midY
}
setNeedsDisplay()
}
方法将根据模型绘制线条。