2009-08-22 98 views
0

我有一个NSView子类可以在其超级视图中拖动。我通过在我的mouseDragged事件处理程序中调用NSView的setFrameOrigin和setFrameRotation方法来移动视图。每次调用都会移动和旋转视图。当第一个NSView在第二个NSView上移动时,NSView会留下工件

我有一个超级视图所包含的这些视图的多个实例。我遇到的问题是,当一个视图被拖拽到另一个视图上时,它会在它正在遮挡的视图上留下伪像。我在行动中记录了a short video。不幸的是,由于视频压缩,这些工件并不是非常明显。

我强烈怀疑这与同时平移和旋转有关。 Quartz Debug显示遮挡(或遮挡)视图的矩形更新为另一个视图拖过它(video here);不知何故,这个矩形会被绘图引擎错误地计算出来,所以应该重新绘制的视图的一部分不是。

踢球者是我不知道如何解决这个问题。我找不到任何方法在文档中手动指定更新矩形,我也不确定那是需要发生的。有任何想法吗?谢谢!

回答

1

您还可以考虑使用CALayers,而不是意见。与视图不同,层旨在与他们的兄弟姐妹堆叠。

对于尽可能最少的解决方案,请尝试使视图层次支持;它可能会也可能不会解决这个问题,但值得一试。

+0

这个解决方案对我很有吸引力,因为我希望使用核心动画来为这些视图所做的某些事情设置动画效果(例如,当另一个视图被拖动到同一个插槽中时,它会转移出来)。可悲的是,简单地给视图一个层并不能解决问题(实际上绘制到该层可能会做到这一点)。如果我要使用CALayer而不是视图,我将如何应对事件? CALayers不从NSRespnder继承。 (对不起,我是Cocoa n00b,对Core Animation基本无能为力。) – 2009-08-23 07:08:20

+0

我的理解是,在某个级别上至少需要一个视图,即使它是托管和控制整个图层层次结构的单个视图。在这种安排下,视图将使用诸如hitTest之类的消息来处理事件,以确定用户正在使用哪些层。 – 2009-08-23 09:56:43

+0

原来我做错了。一旦我调用适当的方法为我的(程序创建的)视图提供CALayer支持,工件就消失了。当然,我的定位和轮换被打破了,但这不是问题的关键。感谢您的建议! – 2009-08-23 23:17:50

0

视图并非真正被设计为以交互方式堆叠。可以做到,但边缘案例比比皆是。

通常,对于这种类型的事情,如果您想在视图中执行拖动操作(请参见草图示例),则可以使用像基础结构的单元格,如果要在两者之间进行拖动,则可以使用拖放式基础结构视图或窗口(或应用程序)。

如果您确实想要将变换后的视图拖到顶部,则需要使被拖动视图下方的视图矩形无效。矩形将需要比被拖动视图遮挡的总面积(未旋转/未转换)大几个像素。这些文物实际上是由舍入误差引起的;对角线仅仅是光栅绘图系统的估计值。

查看方法:

- (void)setNeedsDisplayInRect:(NSRect)invalidRect;