2011-08-25 80 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]; 

其他代碼是一樣的。