2
votes

In my custom NSWindow class, I have a Parent view (set as the window's contentView), with a Child. Throughout my application, I have appended subviews to my Child view, which all appear to receive mouseDown responses perfectly. However, I wanted to have a panel slide into place above the Child view (yet still housed within the parent view) upon clicking of a button (I'm calling it slidingOverlay in my application). Upon adding the slidingOverlay subview (which subsequently contains more subviews) to the Child view, I am unable to click any of its elements, as they all pass on through to the lower, Child view.

A couple details:

  • I have tried overlaying the slidingOverlay as a subview of both the Child view and the Parent view, both resulting in the Child view receiving NSEvents.
  • The slidingOverlay appears to be non-opaque (translucent? not sure if Apple has a term for it), despite being plainly visible, layer-backed, and having a solid color. Perhaps this is the origin? I'm rather new to Cocoa.
  • All three views are actually layer-backed (Parent, Child, and slidingOverlay).
  • All three views were created programmatically.
  • I have tried overriding (NSView*)hitTest:(NSPoint)aPoint for Child, and forwarding the NSEvent to slidingOverlay's subviews works. However, this method seems kinda hack-like and requires me to predetermine which slidingOverlay subview will receive events. I want all slidingOverlay subviews to be able to get clicks, ignoring all lower subviews, while slidingOverlay is visible.

Just to summarize, there is an NSWindow, with a contentView of Parent. Parent has one Child with subviews (NSButtons, drop downs, custom classes, et cetera), all receiving clicks. The slidingOverlay, in its present state, is appended to Child as a subview (which should work fine according to my grasp on things), and its visibility can be toggled. When toggled on the mouseDown NSEvents to slidingOverlay and its children are being passed to the underlying subviews of Child - for instance, clicking point 100,400 will result in the drop down (direct subview of Child, but underneath the visible slidingOverlay layer) to be expanded.

I guess the question is - when an NSView (with containing subviews) is atop another view, how would it be perceived as "solid" and clickable, in favor of it's parent, or underlying views?

2

2 Answers

0
votes

Looks like attaching a new NSWindow (replacing slidingOverlay) works (in favor of further layering Child). Still no idea why NSEvents pierce through after a certain number of subviews are attached, though…

0
votes

It is related to the placement of subviews in their array.

Whenever subviews are overlapping, the subview that added later will take the mouse event. The zPosition in layer-backed views won't help either. You can fix this by sorting the subviews using the following method:

- (void)sortSubviewsUsingFunction:context: