Прагматичный способ работы с мышью в слоях Core Animation

Я начинаю работать с Core Animation, и мне стало интересно, как обрабатывать различные типы событий мыши, например

  1. мышь вошла в CALayer
  2. мышь вышла из CALayer
  3. щелкните мышью на CALayer

На данный момент я концентрируюсь только на mouseDown сообщении, отправленном в мое пользовательское представление. Согласно документации, я должен использовать -hitTest:(CGPoint)point, вызывая на моем корневом уровне (тот, который установлен с [customView setLayer:rootLayer]).

Он должен вернуть самый дальний слой в дереве, который находится в позиции, указанной точкой. Так я и сделал:

[rootLayer hitTest:[event locationInWindow]]

но это не работает. Кажется, работает, если я просто нажимаю rootLayer, иначе возвращается только null. Конечно, подслои добавляются в rootLayer (на самом деле они нарисованы)

Мне не хватает какого-то преобразования координат? Кроме того, можно ли обрабатывать щелчки мышью?

Чтобы узнать, когда мышь входит в CALayer, нужно ли мне проводить тестирование нажатия для каждого обновления движения мыши?

заранее спасибо


person Jack    schedule 07.12.2009    source источник


Ответы (2)


Возможно, вы захотите посмотреть, как мы обрабатываем события мыши / касания в CALayers в рамках Core Plot framework < / а>. Мы создали рудиментарную цепочку респондентов с нашими различными подклассами CALayer в иерархии уровней. Недавно мы добавили код для прокрутки графика с использованием событий мыши / касания в качестве примера того, как использовать этот вид взаимодействия.

Я сам использовал нечто подобное, только с обработкой щелчков мышью в основном представлении размещения слоев. С этой точки зрения я переопределил -mouseDown: и добавил код, подобный следующему:

CGPoint pointOfClick = NSPointToCGPoint([self convertPoint:[theEvent locationInWindow] fromView:nil]);
CALayer *hitLayer = [self.layer hitTest:pointOfClick];
if ( (hitLayer != nil) && [hitLayer isKindOfClass:[MyCustomLayer class]])
{
    [(MyCustomLayer *)hitLayer mouseDown];
}

Класс MyCustomLayer будет настраиваемым подклассом CALayer, который реагирует на метод mouseDown и самостоятельно выполняет некоторую обработку щелчков мышью. В качестве альтернативы вы можете полностью обрабатывать ответ на щелчок мыши в рамках этого метода представления размещения слоев.

Одна вещь, в которой следует убедиться, заключается в том, что если вы создали подкласс CALayer, его -containsPoint: метод по-прежнему возвращает YES, если переданная точка находится в границах вашего слоя. В противном случае -hitTest: проигнорирует этот слой.

person Brad Larson    schedule 08.12.2009
comment
Кажется очевидным, как насчет обработки mouseEntered и mouseExited? Должен ли я имитировать весь процесс, сохраняя фактический слой, на котором находится мышь, и обрабатывает, когда он меняет вход или выход из нового? - person Jack; 08.12.2009
comment
Я не пробовал этого, но вы могли бы создать NSTrackingAreas для каждого из ваших слоев. Если вы сделаете их подклассом CALayer, который отвечает на сообщения -mouseEntered :, -mouseExited :, -mouseMoved: и -cursorUpdate:, вы можете сделать каждый уровень владельцем области отслеживания и напрямую реагировать на эти события. Это может показаться более эффективным, чем проверка нажатия при каждом движении мыши. - person Brad Larson; 09.12.2009

Вам необходимо преобразовать locationInWindow в систему координат содержащего представления. Итак, если ваше представление называется customView, вы должны сделать это:

[rootLayer hitTest:[customView convertPoint:[event locationInWindow] fromView:nil]];

CALayers не получают собственных уведомлений о событиях, поэтому единственный способ обрабатывать события - обрабатывать их в содержащем представлении.

person Alex    schedule 07.12.2009