如何处理mouseEntered:带有圆角的NSView上的事件

时间:2019-03-14 13:09:59

标签: swift xcode cocoa nsview

我正在创建一个带有圆角的视图,并且当鼠标悬停在该视图上时,我希望该视图突出显示。问题是,当鼠标在角落之外时,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 个答案:

答案 0 :(得分:1)

您可以保存路径并使用event检查containsPoint(point: CGPoint)的点是否在内部。 有关更多信息,请参见here

答案 1 :(得分:1)

首先,如果您的圆角足够小,我想说不用担心,只要坚持使用矩形跟踪区域即可。大多数用户不太可能注意到,因此在我看来,这可能不值得您花时间创建。

如Victor所述,如果您仍然想执行此操作,则应使用描述视图形状的贝塞尔曲线进行检查,但比仅在mouseEntered()和{{1 }}。您还需要实现mouseExited()并在那里进行相同的路径检查,以便在光标移入和移出跟踪区域内的路径时正确响应。不要忘记将跟踪区域配置为实际向您发送那些mouseMoved()事件。

您可能还需要开始考虑性能。如果您最终实现了mouseMoved,那么您的测试代码将在跟踪区域中运行光标移动的每一帧,这可能会降低UI的响应速度。如果最终出现问题,可以使用多种优化方法,例如使用不使用mouseMoved的内部跟踪区域(在圆角边缘内部)或增加mouseMoved减少测试计算复杂性的路径。您可能会想到,优化此过程确实非常复杂。