События mouseDragged украдены другим представлением - PullRequest
4 голосов
/ 17 сентября 2011

У меня есть несколько представлений класса MyView (подкласс NSView) внутри другого NSView.MyView реализует -mouseEntered:, -mouseExited:, -mouseDown:, -mouseDragged: и -mouseUp:.

Почти всегда, когда MyView получает событие нажатия мыши, все последующие события перетаскивания мышью принимаются тем же MyView до следующего события мыши.Даже если курсор выходит за пределы MyView.Это ожидаемое поведение.

Иногда MyView получит событие нажатия мыши, но будет получать только перетаскиваемые мышью и события мыши, пока курсор остается внутри MyView.Если курсор перемещается на другой MyView, тогда этот MyView начинает получать перетаскиваемые мышью события (без предварительного получения события мыши) и может получать последующее событие мыши.

В случае, если это имеет значение, событие нажатия мыши создает FooView (подкласс NSView) поверх MyView, а перетаскиваемые мышью события изменяют размер кадра FooView,Это может быть связано, так как я смог воспроизвести проблему только после того, как один из этих FooView был создан.FooView не реализует ни один из методов события мыши.

Я уже давно этим занимаюсь и не смог ни преднамеренно воспроизвести проблему, ни воссоздать проблему в простом примере.Я был бы рад ответить на любые вопросы о моем коде, я просто не уверен, что будет иметь отношение к публикации.

Ответы [ 2 ]

2 голосов
/ 19 сентября 2011

Не уверен, что является основной проблемой (это поведение Какао мне кажется несовместимым) ... но вот один из возможных обходных путей:

  1. В супервизоре создайте переменную экземпляра, отслеживающую MyViewэкземпляр, в котором произошло -mouseDown:.
  2. Когда вы получаете -mouseDragged: in MyView, вместо того, чтобы работать с self, оперируйте ссылкой MyView, хранящейся в суперпредставлении.*

... тогда вы сможете последовательно отслеживать, какой объект перетаскивается, без необходимости запуска собственного цикла событий.

0 голосов
/ 17 сентября 2011

Вам нужно запустить свой собственный цикл отслеживания мыши в представлении, пока мышь не поднимется. Вы можете расширить его для обработки большего количества типов событий, передав их в nextEventMatchingMask :.

- (void)mouseDown:(NSEvent*)event
{
    CGPoint hitPoint = [self pointInViewSpaceFromEvent:event];

    BOOL isDragging = NO;
    BOOL isTracking = YES;

    while (isTracking)
    {       
        switch ([event type])
        {
            case NSLeftMouseDown:
                [self singleMouseDownAtPoint:hitPoint withModifierFlags:[event modifierFlags]];
                break;

            case NSLeftMouseUp:
                isTracking = NO;
                if (isDragging)
                    [self mouseDraggingDidEndAtPoint:hitPoint];
                else
                    [self singleMouseUpAtPoint:hitPoint withEvent:event];
                break;

            case NSLeftMouseDragged:
                if (isDragging)
                    [self mouseDraggingAtPoint:hitPoint withModifierFlags:[event modifierFlags]];
                else
                    isDragging = YES;
                break;
            default:
                break;
        }

        if (isTracking)
        {
            event = [[self window] nextEventMatchingMask:NSLeftMouseDraggedMask | NSLeftMouseUpMask];
            hitPoint = [self pointInViewSpaceFromEvent:event];
        }
    }
}
...