Mouse Input / Output Events on Partially Hidden NSViews

I have a problem that, in my opinion, is solvable with some hackers, but I am very curious if there is an easier way to get a job without having to do all this.

I have a stack of NSViews (with layer support, if that helps in some solutions), as shown below:

The view stack / layout

, , . , , . , , , , . , ( ) , , .

SO - , , mouseEntered: mouseExited: ?

, , NSTrackingArea visibleRect , , . , visibleRect "" , . - , NSView. , , - , , .

-, , sub-NSView , ... "" , , .

- ? , ?

!

+5
4

, , , , mouseMoved. 3 , mouseEntered mouseExited , hitTest, , . .

@implementation MainView
@synthesize oldView;

-(void)awakeFromNib {
    oldView = nil;
    Card *card1 = [[Card alloc]initWithFrame:NSMakeRect(150, 150, 200, 150) color:[NSColor redColor] name:@"Red Box"];
    NSTrackingArea *area1 = [[NSTrackingArea alloc]initWithRect:card1.frame options:NSTrackingMouseEnteredAndExited|NSTrackingActiveInActiveApp owner:self userInfo:nil];
    [self addTrackingArea:area1];
    [self addSubview:card1];

    Card *card2 = [[Card alloc]initWithFrame:NSMakeRect(180, 120, 200, 150) color:[NSColor yellowColor] name:@"Yellow Box"];
    NSTrackingArea *area2 = [[NSTrackingArea alloc]initWithRect:card2.frame options:NSTrackingMouseEnteredAndExited|NSTrackingActiveInActiveApp owner:self userInfo:nil];
    [self addTrackingArea:area2];
    [self addSubview:card2];

    Card *card3 = [[Card alloc]initWithFrame:NSMakeRect(210, 90, 200, 150) color:[NSColor greenColor] name:@"Green Box"];
    NSTrackingArea *area3 = [[NSTrackingArea alloc]initWithRect:card3.frame options:NSTrackingMouseEnteredAndExited|NSTrackingActiveInActiveApp owner:self userInfo:nil];
    [self addTrackingArea:area3];
    [self addSubview:card3];
}

-(void)mouseEntered:(NSEvent *)theEvent {
    [self reportTopView:theEvent];
}

-(void)mouseExited:(NSEvent *)theEvent {
    [self reportTopView:theEvent];
}

-(void)reportTopView:(NSEvent *)theEvent {
    id topView = [self hitTest:[theEvent locationInWindow]];
    if (![topView isEqual:oldView]) {
        oldView = topView;
        ([topView isKindOfClass:[Card class]])? NSLog(@"%@",[(Card *)topView name]):NULL;
    }
}

, ( ):

@implementation Card
@synthesize name,fillColor;

- (id)initWithFrame:(NSRect)frame color:(NSColor *)color name:(NSString *)aName{
    self = [super initWithFrame:frame];
    if (self) {
        self.fillColor = color;
        self.name = aName;
    }
    return self;
}

- (void)drawRect:(NSRect)rect {
    [self.fillColor drawSwatchInRect:rect];

}
+3

- Twitter Troughton-Smith. :

, NSTrackingArea . .

hitTest:, , , ( , ).

" " , .

. , , - .

!

+1

:

, , hitTest , . :

 window.view.hitTest(window.mousePos) === self/*sudo code*/

, , . , , "" "", , .

:
https://gist.github.com/eonist/537ae53b86d5fc332fd3

: (perma link)
http://stylekit.org/blog/2015/12/20/Overlapping-tracking-areas/

Example

VS :

enter image description here

+1

Example

, . ( )

, :

http://stylekit.org/blog/2016/01/28/Hit-testing-sub-views/

it includes the use of the method provided by apple: CGPathContainsPoint (path, transformation, point)

If you follow the link to this blog post and then check out the styleKit repository on github from there. You will find the code needed to get the above gif animation example. I provide this as a pointer to an answer, as it can take significantly less time than trying to examine it yourself. I use this technique in all elements of the user interface and it works flawlessly.

Example

0
source

All Articles