Я рисую прямоугольник на пользовательском подклассе NSView, который затем можно перетаскивать в пределах границ вида:

Код для этого:
// Get the starting location of the mouse down event.
NSPoint location = [self convertPoint: [event locationInWindow] fromView: nil];
// Break out if this is not within the bounds of the rect.
if (!NSPointInRect(location, [self boundsOfAllControlPoints])) {
return;
}
while (YES) {
// Begin modal mouse tracking, looking for mouse dragged and mouse up events
NSEvent *trackingEvent = [[self window] nextEventMatchingMask:(NSLeftMouseDraggedMask | NSLeftMouseUpMask)];
// Get tracking location and convert it to point in the view.
NSPoint trackingLocation = [self convertPoint:[trackingEvent locationInWindow] fromView:nil];
// Calculate the delta's of x and y compared to the previous point.
long dX = location.x - trackingLocation.x;
long dY = location.y - trackingLocation.y;
// Update all points in the rect
for (int i = 0; i < 4; i++) {
NSPoint newPoint = NSMakePoint(points[i].x - dX, points[i].y - dY);
points[i] = newPoint;
}
NSLog(@"Tracking location x: %f y: %f", trackingLocation.x, trackingLocation.y);
// Set current location as previous location.
location = trackingLocation;
// Ask for a redraw.
[self setNeedsDisplay:YES];
// Stop mouse tracking if a mouse up is received.
if ([trackingEvent type] == NSLeftMouseUp) {
break;
}
}
Я в основном ловлю событие нажатия мыши и проверяю, находится ли оно внутри перетаскиваемого прямоугольника.Если это так, я начинаю отслеживать движение мыши в trackingEvent.Я вычисляю дельту для координат x и y, создаю новые точки для перетаскиваемого прямоугольника и запрашиваю обновление отображения представлений.
Хотя это работает, оно выглядит немного «любительским», как во время перетаскивания,указатель мыши догонит перетаскиваемую фигуру и в конечном итоге пересечет ее границы.В других операциях перетаскивания указатель мыши будет зафиксирован на месте перетаскиваемого объекта от начала до конца операции перетаскивания.
Что вызывает этот эффект?
РЕДАКТИРОВАТЬ:
Я изменил свой подход после ответа Роба и принял метод трех методов:
- (void) mouseDown: (NSEvent*) event {
// There was a mouse down event which might be in the thumbnail rect.
[self setDragStartPoint: [self convertPoint: [event locationInWindow] fromView: nil]];
// Indicate we have a valid start of a drag.
if (NSPointInRect([self dragStartPoint], [self boundsOfAllControlPoints])) {
[self setValidDrag: YES];
}
}
- (void) mouseDragged: (NSEvent *) anEvent {
// Return if a valid drag was not detected during a mouse down event.
if (![self validDrag]) {
return;
}
NSLog(@"Tracking a drag.");
// Get tracking location and convert it to point in the view.
NSPoint trackingLocation = [self convertPoint: [anEvent locationInWindow] fromView: nil];
// Calculate the delta's of x and y compared to the previous point.
long dX = [self dragStartPoint].x - trackingLocation.x;
long dY = [self dragStartPoint].y - trackingLocation.y;
// Update all points in the rect
for (int i = 0; i < 4; i++) {
NSPoint newPoint = NSMakePoint(points[i].x - dX, points[i].y - dY);
points[i] = newPoint;
}
// Ask for a redraw.
[self setNeedsDisplay:YES];
NSLog(@"Tracking location x: %f y: %f", trackingLocation.x, trackingLocation.y);
// Set current location as previous location.
[self setDragStartPoint: trackingLocation];
NSLog(@"Completed mouseDragged method. Allow for repaint.");
}
- (void) mouseUp: (NSEvent *) anEvent {
// End the drag.
[self setValidDrag: NO];
[self setNeedsDisplay: YES];
}
Хотя эффект немного лучше, все еще есть заметная задержка спрямоугольник в итоге перетаскивается за направление движения указателя мыши.Это особенно заметно, когда я медленно двигаю мышь во время перетаскивания.
EDIT 2:
Понял.Проблема была с подсчетом дельт.Я использовал долго для этого, в то время как я должен использовать float.Отлично работает сейчас.