Raf*_*ael 5 cocoa nsevent calayer nswindow
假设我有一个浮动的、无边框的、圆形的NSWindow
。
它是圆形的,因为内容视图只是绘制了一个红色圆圈。
该内容视图需要是图层支持的 ( [contentView setWantsLayer:YES]
),因为我正在其上应用CoreAnimations,例如动画缩放。
通常,NSWindow 的可点击区域是由内容视图像素的透明度定义的。然而,不幸的是,一旦 NSWindow 的内容视图变得受图层支持,透明区域也会收到点击。
就我而言,这是一个严重的问题,因为我只想接收半径内的点击。但现在,在窗口矩形内但超出圆半径的单击将激活窗口(从而激活整个应用程序),但事实并非如此。该窗口还可以通过其内容视图的一角进行拖动。
我最初的想法是在子类中实现[NSWindow sendEvent:]
并检查单击是否在半径内执行,使用[theEvent locationInWindow]
. 我想我可以简单地丢弃该事件,如果它超出了半径,那么就不再调用[super sendEvent:theEvent]
。然而这不起作用:我注意到, mouseDown:; window 方法甚至在 sendEvent:; 之前被调用 方法。
我搜索了很多,但我发现的唯一想法是在窗口顶部有一个类似非层支持的 NSWindow 的代理,它有条件地委托点击,但这会导致不可预测的 UI 行为。
你们有什么想法,如何解决吗?
几周后,我得到了以下结果:
A)代理窗口:利用非层支持的代理窗口,它作为子窗口放置在目标窗口之上。代理窗口与目标窗口具有相同的形状,并且由于它没有层支持,因此它将正确接收和忽略事件。代理窗口通过覆盖将所有事件委托给目标窗口sendEvent:
。目标窗口设置为忽略所有鼠标事件。
B)全局鼠标指针观察:使用和安装全局和本地事件监视器来监视NSMouseMovedMask|NSLeftMouseDraggedMask
事件addGlobalMonitorForEventsMatchingMask
addLocalMonitorForEventsMatchingMask
。事件监视器根据当前全局鼠标位置禁用和启用忽略所有已注册目标窗口上的鼠标事件。对于圆形窗口,必须计算鼠标指针与每个目标窗口之间的距离。
一般来说,这两种方法都工作得很好,但是我遇到了子窗口方法的一些不可预测的错误行为(子窗口与其父窗口的位置“不同步”)。
更新:两种方法都有一些明显的缺点:在A)中,代理窗口有时可能不同步,并且可能稍微偏离实际窗口。
在 B) 中,即使应用程序不是最前面的应用程序,事件监视器在移动鼠标时也会对电池寿命产生很大影响。
归档时间: |
|
查看次数: |
2059 次 |
最近记录: |