【问题标题】:NSView leaves artifacts on another NSView when the first is moved across the second当第一个移过第二个时,NSView 会在另一个 NSView 上留下工件
【发布时间】:2010-11-21 23:34:40
【问题描述】:

我有一个可以在其父视图中拖动的 NSView 子类。我通过在 mouseDragged 事件处理程序中调用 NSView 的 setFrameOrigin 和 setFrameRotation 方法来移动视图。每次调用都会移动和旋转视图。

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

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

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

【问题讨论】:

    标签: cocoa drawing nsview


    【解决方案1】:

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

    一般来说,对于这种事情,如果你想在视图中拖动,你会使用类似 Cell 的基础设施(参见 Sketch 示例),如果你想在视图之间拖动,你会使用拖放基础设施或窗口(或应用程序)。

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

    看方法:

    - (void)setNeedsDisplayInRect:(NSRect)invalidRect;
    

    【讨论】:

      【解决方案2】:

      您也可以考虑使用 CALayers 代替视图。与视图不同,层 旨在与其同级堆叠。

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

      【讨论】:

      • 这个解决方案对我很有吸引力,因为我曾想使用 Core Animation 为这些视图所做的某些事情设置动画(比如当另一个视图被拖到同一个插槽时移开)。可悲的是,简单地给视图一个层并不能解决问题(实际上绘制到该层可能会解决问题)。如果我使用 CALayer 而不是视图,我将如何响应事件? CALayers 不继承自 NSRespnder。 (抱歉,我是 Cocoa n00b,对 Core Animation 基本上一无所知。)
      • 我的理解是,您在某个级别至少需要一个视图,即使它是托管和控制整个层层次结构的单个视图。在这种安排下,视图将处理事件,使用诸如hitTest: 之类的消息来确定用户正在使用哪些层。
      • 原来我做错了。一旦我调用了正确的方法来为我的(以编程方式创建的)视图提供 CALayer 支持,工件就消失了。当然,我的定位和轮换都坏了,但这不是手头的问题。感谢您的建议!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-11
      • 2017-12-09
      • 2012-06-09
      相关资源
      最近更新 更多