2011-08-25 8 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

この問題にアプローチする最善の方法は、座標空間を確実に理解することから始めることです。

まず、ウィンドウの「フレーム」について話すとき、それはスーパービューの座標空間にあることを理解することが重要です。これは、ビュー自体の内部を何も変更していないため、ビュー自体の反転を調整しても実際には違いが生じないことを意味します。

しかし、ここでは反転が重要であるというあなたの直感は正しいです。

デフォルトでは、入力したコードは正常に動作するようです。あなたのスーパービューが反転している(または反転していない)かもしれませんし、それはあなたが期待している座標空間とは異なる座標空間にあります。

ランダムにビューを反転したり反転したりするのではなく、対処しているポイントを既知の座標空間に変換することをお勧めします。

フレーム原点を扱っているので、上記のコードを編集して常にスーパービューの座標空間に変換しました。これは、ドラッグ可能なビューが反転された、または反転されていないスーパービューに置かれている場合に機能します。

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

他のコードは同じです。

関連する問題