子视图越界 NSScrollView 响应鼠标事件
Subviews out of bounds of NSScrollView respond to mouse event
我的问题是我的 scrollView 的子视图响应鼠标事件,即使它们不可见(在 scrollView 可见部分的边界之外)。
我有这个架构:
CustomView *view01 = [[CustomView alloc] init];
CustomView *view02 = [[CustomView alloc] init];
NSView *contentView = [[NSView alloc] init];
[contentView addSubview:view01];
[contentView addSubview:view02];
NSSCrollView *scrollView = [[NSScrollView alloc] init];
scrollView setDocumentView:contentView];
使用 CustomView 实现:
#import "CustomView.h"
@interface CustomView ()
{
NSTrackingArea *trackingArea;
}
@end
@implementation CustomView
-(id)initWithFrame:(NSRect)contentRect
{
if(self = [super initWithFrame:(NSRect)contentRect])
{
[self setFrame:contentRect];
}
return self;
}
- (void)mouseDown: (NSEvent*)event
{
NSLog(@"mouseDown:");
[NSApp preventWindowOrdering];
}
- (BOOL)shouldDelayWindowOrderingForEvent:(NSEvent *)evt
{
return YES;
}
-(BOOL)acceptsFirstResponder
{
return YES;
}
-(void)updateTrackingAreas
{
if(trackingArea != nil)
{
[self removeTrackingArea:trackingArea];
}
int opts = (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways);
trackingArea = [ [NSTrackingArea alloc] initWithRect:[self bounds]
options:opts
owner:self
userInfo:nil];
[self addTrackingArea:trackingArea];
}
- (void)mouseEntered:(NSEvent *)theEvent
{
NSLog(@"mouseEntered:");
}
- (void)mouseExited:(NSEvent *)theEvent
{
NSLog(@"mouseExited:");
}
- (NSView *)hitTest:(NSPoint)aPoint
{
return NSPointInRect(aPoint, self.frame) ? self : nil;
}
@end
终于找到问题了
我需要在方法中添加选项 NSTrackingInVisibleRect :
-(void)updateTrackingAreas
{
if(trackingArea != nil)
{
[self removeTrackingArea:trackingArea];
}
int opts = (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways| NSTrackingInVisibleRect);
trackingArea = [ [NSTrackingArea alloc] initWithRect:[self bounds]
options:opts
owner:self
userInfo:nil];
[self addTrackingArea:trackingArea];
}
然后,当CustomView的一部分在scrollView之外时,不响应mouseEntered和mouseExited。
我的问题是我的 scrollView 的子视图响应鼠标事件,即使它们不可见(在 scrollView 可见部分的边界之外)。
我有这个架构:
CustomView *view01 = [[CustomView alloc] init];
CustomView *view02 = [[CustomView alloc] init];
NSView *contentView = [[NSView alloc] init];
[contentView addSubview:view01];
[contentView addSubview:view02];
NSSCrollView *scrollView = [[NSScrollView alloc] init];
scrollView setDocumentView:contentView];
使用 CustomView 实现:
#import "CustomView.h"
@interface CustomView ()
{
NSTrackingArea *trackingArea;
}
@end
@implementation CustomView
-(id)initWithFrame:(NSRect)contentRect
{
if(self = [super initWithFrame:(NSRect)contentRect])
{
[self setFrame:contentRect];
}
return self;
}
- (void)mouseDown: (NSEvent*)event
{
NSLog(@"mouseDown:");
[NSApp preventWindowOrdering];
}
- (BOOL)shouldDelayWindowOrderingForEvent:(NSEvent *)evt
{
return YES;
}
-(BOOL)acceptsFirstResponder
{
return YES;
}
-(void)updateTrackingAreas
{
if(trackingArea != nil)
{
[self removeTrackingArea:trackingArea];
}
int opts = (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways);
trackingArea = [ [NSTrackingArea alloc] initWithRect:[self bounds]
options:opts
owner:self
userInfo:nil];
[self addTrackingArea:trackingArea];
}
- (void)mouseEntered:(NSEvent *)theEvent
{
NSLog(@"mouseEntered:");
}
- (void)mouseExited:(NSEvent *)theEvent
{
NSLog(@"mouseExited:");
}
- (NSView *)hitTest:(NSPoint)aPoint
{
return NSPointInRect(aPoint, self.frame) ? self : nil;
}
@end
终于找到问题了
我需要在方法中添加选项 NSTrackingInVisibleRect :
-(void)updateTrackingAreas
{
if(trackingArea != nil)
{
[self removeTrackingArea:trackingArea];
}
int opts = (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways| NSTrackingInVisibleRect);
trackingArea = [ [NSTrackingArea alloc] initWithRect:[self bounds]
options:opts
owner:self
userInfo:nil];
[self addTrackingArea:trackingArea];
}
然后,当CustomView的一部分在scrollView之外时,不响应mouseEntered和mouseExited。