objective-c – mouseExited不会在鼠标离开trackingArea时滚动时调用

objective-c – mouseExited不会在鼠标离开trackingArea时滚动时调用,第1张

概述为什么当鼠标通过滚动或做动画从NStrackingArea退出时不调用mouseExited / mouseEntered? 我创建如下代码: 鼠标进入和退出: -(void)mouseEntered:(NSEvent *)theEvent { NSLog(@"Mouse entered");}-(void)mouseExited:(NSEvent *)theEvent{ 为什么当鼠标通过滚动或做动画从NStrackingArea退出时不调用mouseExited / mouseEntered?

我创建如下代码:

鼠标进入和退出:

-(voID)mouseEntered:(NSEvent *)theEvent {    NSLog(@"Mouse entered");}-(voID)mouseExited:(NSEvent *)theEvent{    NSLog(@"Mouse exited");}

跟踪区域:

-(voID)updateTrackingAreas{     if(trackingArea != nil) {        [self removeTrackingArea:trackingArea];        [trackingArea release];    }    int opts = (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways);    trackingArea = [ [NSTrackingArea alloc] initWithRect:[self bounds]                                             options:opts                                               owner:self                                            userInfo:nil];    [self addTrackingArea:trackingArea];}

更多细节:

我在NSScrollVIEw的视图中添加了NSVIEws作为子视图。每个NSVIEw有自己的跟踪区域,当我滚动我的scrollVIEw和离开跟踪区域“mouseExited”没有调用,但没有滚动一切工作正常。问题是,当我滚动“updateTrackingAreas”被调用,我认为这造成问题。

*同样的问题,只是NSVIEw没有添加它作为子视图,这不是一个问题。

解决方法 正如你在问题的标题中指出的,mouseEntered和mouseExited仅在鼠标移动时调用。要了解为什么会出现这种情况,让我们先看看第一次添加NSTrackingAreas的过程。

作为一个简单的例子,让我们创建一个通常绘制一个白色背景的视图,但如果用户悬停在视图上,它绘制一个红色的背景。此示例使用ARC。

@interface ExampleVIEw- (voID) createTrackingArea@property (nonatomic,retain) backgroundcolor;@property (nonatomic,retain) trackingArea;@end@implementation ExampleVIEw@synthesize backgroundcolor;@synthesize trackingArea- (ID) awakeFromNib{    [self setBackgroundcolor: [NScolor whitecolor]];    [self createTrackingArea];}- (voID) createTrackingArea{    int opts = (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways);    trackingArea = [ [NSTrackingArea alloc] initWithRect:[self bounds]                                             options:opts                                               owner:self                                            userInfo:nil];    [self addTrackingArea:trackingArea];}- (voID) drawRect: (NSRect) rect{    [[self backgroundcolor] set];    NSRectFill(rect);}- (voID) mouseEntered: (NSEvent*) theEvent{    [self setBackgroundcolor: [NScolor redcolor]];}- (voID) mouseEntered: (NSEvent*) theEvent{    [self setBackgroundcolor: [NScolor whitecolor]];}@end

这个代码有两个问题。首先,当调用-awakeFromNib时,如果鼠标已经在视图中,则不调用-mouseEntered。这意味着背景将仍然是白色的,即使鼠标在视图上。这实际上在NSVIEw文档中提到的-addTrackingRect的assumeInsIDe参数:owner:userData:assumeInsIDe:

If YES,the first event will be generated when the cursor leaves aRect,regardless if the cursor is insIDe aRect when the tracking rectangle is added. If NO the first event will be generated when the cursor leaves aRect if the cursor is initially insIDe aRect,or when the cursor enters aRect if the cursor is initially outsIDe aRect.

在这两种情况下,如果鼠标位于跟踪区域内,则在鼠标离开跟踪区域之前不会生成事件。

所以要解决这个问题,当我们添加跟踪区域时,我们需要找出光标是否在跟踪区域内。因此,我们的-createTrackingArea方法变成了

- (voID) createTrackingArea{    int opts = (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways);    trackingArea = [ [NSTrackingArea alloc] initWithRect:[self bounds]                                             options:opts                                               owner:self                                            userInfo:nil];    [self addTrackingArea:trackingArea];    NSPoint mouseLocation = [[self window] mouseLocationOutsIDeOfEventStream];    mouseLocation = [self convertPoint: mouseLocation                              fromVIEw: nil];    if (NSPointInRect(mouseLocation,[self bounds]))    {        [self mouseEntered: nil];    }    else    {        [self mouseExited: nil];    }}

第二个问题是滚动。当滚动或移动视图时,我们需要在该视图中重新计算NSTrackingAreas。这是通过删除跟踪区域,然后将其添加回来。如您所知,-updateTrackingAreas当您滚动视图时调用。这是删除和重新添加区域的地方。

- (voID) updateTrackingAreas{    [self removeTrackingArea:trackingArea];    [self createTrackingArea];    [super updateTrackingAreas]; // Needed,according to the NSVIEw documentation}

这应该照顾你的问题。不可否认,需要找到鼠标位置,然后将其转换为查看坐标,每次添加一个跟踪区域是快速老,所以我建议在NSVIEw上创建一个类别,自动处理这个。你不会总是能够调用[self mouseEntered:nil]或[self mouseExited:nil],所以你可能想让类别接受几个块。一个运行,如果鼠标在NSTrackingArea,一个运行,如果不是。

总结

以上是内存溢出为你收集整理的objective-c – mouseExited不会在鼠标离开trackingArea时滚动时调用全部内容,希望文章能够帮你解决objective-c – mouseExited不会在鼠标离开trackingArea时滚动时调用所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1042397.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-24
下一篇 2022-05-24

发表评论

登录后才能评论

评论列表(0条)

保存