Как обрабатывать mouseEntered: события в NSView с закругленными углами - PullRequest
0 голосов
/ 14 марта 2019

Я создаю вид с закругленными углами, и я хочу, чтобы вид выделялся при наведении на него курсора мыши.Проблема в том, что NSTrackingArea регистрирует событие mouseEntered:, когда мышь находится за пределами углов.Есть ли способ переопределить, как он определяет, находится ли он в представлении?

Я пробовал:

  • Добавление .inVisibleRect в NSTrackingArea.Options
  • Переопределение isMousePoint:in:

При необходимости я могу реализовать mouseEntered:, чтобы игнорировать все события, точки которых не находятся внутри прямоугольника, но мне было интересно, есть ли более элегантный способ (например, где mouseEntered: вызывается только тогда, когда мышь фактически входит в вид).

Это код, который я использую для рисования (он работает для меня):

...

override func draw(_ dirtyRect: NSRect)
{
    let path = NSBezierPath(roundedRect: dirtyRect, xRadius: radius, yRadius: radius)
    path.addClip()

    backgroundColor.setFill()
    dirtyRect.fill()
}

...

override func mouseEntered(with event: NSEvent) 
{
    print("Mouse entered!")
}

Дайте мне знать, если смогууточнить что угодно.Спасибо за помощь!

Ответы [ 2 ]

1 голос
/ 14 марта 2019

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

Если вы все еще хотите сделать это, как упомянул Виктор, вам следует проверить, используя какой-либо путь Безье, описывающий форму вашего представления, но это немного сложнее, чем просто проверить это внутри mouseEntered() и mouseExited(). Вам также необходимо внедрить mouseMoved() и выполнить ту же проверку пути там, чтобы правильно реагировать, когда курсор перемещается внутрь и наружу пути в пределах области отслеживания. Не забудьте настроить область отслеживания так, чтобы она действительно отправляла вам эти mouseMoved события.

Возможно, вам также придется задуматься о производительности. Если вы в конечном итоге реализуете mouseMoved, тогда ваш тестовый код будет проходить каждый кадр движения курсора через область отслеживания, что потенциально может снизить скорость отклика вашего пользовательского интерфейса. Существует ряд оптимизаций, которые можно использовать, если это приводит к возникновению проблемы, например, использование внутренней области отслеживания (внутри закругленных краев), в которой не используется mouseMoved, или увеличение flatness пути для уменьшения сложность тестового расчета. Как вы можете себе представить, оптимизировать это очень сложно.

1 голос
/ 14 марта 2019

Вы можете сохранить путь и проверить, находится ли точка event внутри или нет, используя containsPoint(point: CGPoint).Подробнее см. здесь .

...