NSView leaves artifacts on another NSView when the first is moved across the second

北城以北 提交于 2019-12-13 06:16:13

问题


I have an NSView subclass that can be dragged around in its superview. I move the views by calling NSView's setFrameOrigin and setFrameRotation methods in my mouseDragged event handler. The views are both moved and rotated with each call.

I have multiple instances of these views contained by a single superview. The problem I'm having is that, as one view is dragged over another, it leaves artifacts behind on the view it's eclipsing. I recorded a short video of this in action. Unfortunately, due to the video compression the artifacts aren't very visible.

I strongly suspect that this is related to the simultaneous translation and rotation. Quartz Debug reveals that a rectangle of the occluding (or occluded) view is updated as another view is dragged across it (video here); somehow this rectangle is getting miscalculated by the drawing engine, so part of the view that should be redrawn isn't.

The kicker is I have no idea how to fix this. I can't find any way to manually specify the update rect in the docs, nor am I sure that's what needs to happen. Any ideas? Thanks!


回答1:


You might also consider using CALayers instead of views. Unlike views, layers are intended to be stacked with their siblings.

For a possible least-effort solution, try making the views layer-backed; it may or may not solve this problem, but it's worth a try.




回答2:


Views aren't really designed to be stacked in an interactive fashion. Can be done, but edge cases abound.

Generally, for this kind of thing you would use a Cell like infrastructure if you want to do in-view dragging (See the Sketch example) and you would use the drag-n-drop infrastructure if you want to drag between views or windows (or apps).

If you really want to drag a transformed view over the top, you'll need to invalidate a rectangle of the view underneath the view being dragged. The rectangle will need to be bigger by a few pixels than the total area (unrotated/untransformed) that is obscured by the view being dragged. The artifacts are, effectively, caused by rounding error; diagonal lines are just an estimate on a raster drawing system.

See the method:

- (void)setNeedsDisplayInRect:(NSRect)invalidRect;


来源:https://stackoverflow.com/questions/1317269/nsview-leaves-artifacts-on-another-nsview-when-the-first-is-moved-across-the-sec

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!