2011-08-25 214 views
9

我有一个NSView,我将添加为另一个NSView的子视图。我希望能够围绕父视图拖动第一个NSView。我有一些部分工作的代码,但NSView在我的鼠标拖动方向上沿Y轴的相反方向移动时出现问题。 (即,我拖下来,它向上和相反)。NSView:拖动视图

这里是我的代码:

// -------------------- 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; 
} 

视图被翻转,虽然我改变了回默认,它似乎并没有发挥作用。我究竟做错了什么?

回答

13

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

首先,理解当我们谈论窗口的“框架”时,它是在超级视图的坐标空间中是至关重要的。这意味着调整视图本身的翻转实际上并不会产生影响,因为我们没有改变视图内部的任何东西。

但是你的直觉认为翻转在这里很重要。

默认情况下,您的代码,键入,似乎它会工作;也许你的超级观点已被翻转(或不翻转),并且它处于一个不同的坐标空间中,而不是你期望的。

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

我编辑了上面的代码,总是转换成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

0

我想你应该根据我的测试,根据鼠标的位置计算,造成的,它变得更加smooth.Because方式像下面只提供应用程序的窗口内的位置坐标系:

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

w ^我建议的帽子是这样的:

lastDrag = [NSEvent mouseLocation]; 

其他代码是一样的。