在可可中拖动一个矩形

在可可中拖动一个矩形,第1张

概述我在NSView的自定义子类上绘制一个矩形,然后可以在视图的边框内拖动: 这样做的代码是: // Get the starting location of the mouse down event.NSPoint location = [self convertPoint: [event locationInWindow] fromView: nil];// Break out if thi 我在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坐标的delta,为可拖动的rect创建新点,并请求刷新视图显示.

尽管它有效,但它看起来有点“业余”,因为在拖动过程中,鼠标指针会赶上被拖动的形状并最终越过它的边界.在其他拖动 *** 作中,从拖动 *** 作的开始到结束,将看到鼠标指针固定到被拖动对象的位置.

是什么导致了这种影响?

编辑:

在Rob的回答之后我改变了我的方法并采用了三种方法:

- (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.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];}

尽管效果略好一些,但是最终拖动鼠标指针的移动方向仍然存在明显的延迟.当我在拖动过程中缓慢移动鼠标时,这一点尤为明显.

编辑2:

得到它了.问题在于计算增量.我用了很长时间,但我应该使用浮动.现在很棒.

解决方法 您在绘制期间保持事件循环,这意味着正方形永远不会重绘.您对setNeedsdisplay的调用:不会绘制任何内容.它只标记要重绘的视图.在此例程返回之前,它无法重绘,在释放鼠标按钮之前,您不会执行此 *** 作.

阅读Handling Mouse Dragging Operations以获得有关如何在Cocoa中实现拖动的完整讨论.您需要从mouseDown:返回并覆盖mouseDragged:和mouseUp:,或者您需要自己抽取事件循环以便绘制周期可以处理.

我倾向于推荐第一种方法,即使它需要多种方法.抽取事件循环可能会产生非常令人惊讶的错误,应谨慎使用.我经验中最常见的错误是由于在您抽取事件循环时延迟选择器触发,导致“额外”代码在拖动例程中运行.在某些情况下,这可能会导致重入和死锁. (我发生过这种情况……)

总结

以上是内存溢出为你收集整理的在可可中拖动一个矩形全部内容,希望文章能够帮你解决在可可中拖动一个矩形所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1018325.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存