NSView:拖动视图

时间:2011-08-25 19:05:42

标签: objective-c nsview drag

我有一个NSView,我将其作为另一个NSView的子视图添加。我希望能够在父视图周围拖动第一个NSView。我有一些部分工作的代码,但是在我的鼠标拖动时,NSView在Y轴上向相反方向移动存在问题。 (即我向下拖动,向上移动,然后向上移动)。

这是我的代码:

// -------------------- MOUSE EVENTS ------------------- \\ 

- (BOOL) acceptsFirstMouse:(NSEvent *)e {
return YES;
}

- (void)mouseDown:(NSEvent *) e { 

//get the mouse point
lastDragLocation = [e locationInWindow];

}

- (void)mouseDragged:(NSEvent *)theEvent {

NSPoint newDragLocation = [theEvent locationInWindow];
NSPoint thisOrigin = [self frame].origin;
thisOrigin.x += (-lastDragLocation.x + newDragLocation.x);
thisOrigin.y += (-lastDragLocation.y + newDragLocation.y);
[self setFrameOrigin:thisOrigin];
lastDragLocation = newDragLocation;
}

视图被翻转,虽然我将其更改回默认值,但似乎没有任何区别。我究竟做错了什么?

2 个答案:

答案 0 :(得分:13)

解决这个问题的最好方法是从对坐标空间的充分理解开始。

首先,了解当我们谈论窗口的“框架”时,它必须位于 superview 的坐标空间中。这意味着调整视图本身的翻转性实际上不会产生影响,因为我们没有改变视图本身内部的任何内容。

但你认为翻转很重要的直觉是正确的。

默认情况下,您键入的代码似乎可以正常工作;也许你的超级视图被翻转(或没有翻转),它的坐标空间与你预期的不同。

最好将您正在处理的点转换为已知的坐标空间,而不是随意翻转和翻转视图。

我已经编辑了上面的代码,以便始终转换为superview的坐标空间,因为我们正在处理帧原点。如果您的可拖动视图放置在翻转或非翻转的超视图中,这将起作用。

// -------------------- MOUSE EVENTS ------------------- \\ 

- (BOOL) acceptsFirstMouse:(NSEvent *)e {
    return YES;
}

- (void)mouseDown:(NSEvent *) e { 

    // Convert to superview's coordinate space
    self.lastDragLocation = [[self superview] convertPoint:[e locationInWindow] fromView:nil]; 

}

- (void)mouseDragged:(NSEvent *)theEvent {

    // We're working only in the superview's coordinate space, so we always convert.
    NSPoint newDragLocation = [[self superview] convertPoint:[theEvent locationInWindow] fromView:nil];
    NSPoint thisOrigin = [self frame].origin;
    thisOrigin.x += (-self.lastDragLocation.x + newDragLocation.x);
    thisOrigin.y += (-self.lastDragLocation.y + newDragLocation.y);
    [self setFrameOrigin:thisOrigin];
    self.lastDragLocation = newDragLocation;
}

此外,我建议您重构代码以简单地处理原始鼠标按下位置和指针的当前位置,而不是处理mouseDragged事件之间的增量。这可能会导致意想不到的结果。

而是简单地在拖动视图的原点和鼠标指针(鼠标指针在视图中)之间存储偏移量,并将帧原点设置为鼠标指针的位置减去偏移量。

这是一些额外的阅读:

Cocoa Drawing Guide

Cocoa Event Handling Guide

答案 1 :(得分:0)

我认为你应该根据鼠标的位置来计算,因为根据我的测试,它会变得更加平滑。因为下面的方式只提供应用程序窗口坐标系内的位置:

[[self superview] convertPoint:[theEvent locationInWindow] fromView:nil];

我的建议是这样的:

lastDrag = [NSEvent mouseLocation];

其他代码也是一样。