objective-c - 部分隐藏的 NSView 上的鼠标进入/退出事件

标签 objective-c macos cocoa mouse nsview

我有一个问题,我认为可以通过一些 hacker 来解决,但我很好奇是否有更简单的方法来完成工作而不必做所有这些。

我有一堆 NSView(层支持,如果它以某种方式帮助提供一些更好的解决方案),如下所示:

The view stack/layout

这里的问题是,这本质上是一个菜单,但对悬停敏感。如果用户将鼠标悬停在较低级别 View 的公开部分之一上,我需要根据该 View 执行操作。这是一个动态系统,因此像这样堆叠的菜单项的数量可能会发生变化,从而使静态计算更加困难。如您所见,它们基本上都是第一项的副本(按形状),但随着您通过简单的变换旋转在堆栈中向下移动一点点。

我向 SO 社区提出的问题是,你们认为获得 mouseEntered: 和 mouseExited: 事件的最佳方法是什么,仅针对这些 View 的字面可见部分?

我试图做的是在这些 View 的 visibleRect 部分使用 NSTrackingArea,这听起来比在这种情况下实际要方便得多。实际上,visibleRect 似乎始终对它们所有人“可见”。除了部分重叠的 NSView 之外,没有任何东西被显式阻止或隐藏。所发生的一切是我从所有 View 中收到一个垃圾邮件控制台,同时尖叫着鼠标进入了它们的矩形。

我正在考虑的是为每个菜单项制作子 NSView,并让每个菜单项负责跟踪区域……每个菜单项都有一个沿右侧和底部的“条形” View ,可以报告,但是这仍然有点骇人听闻,而且很恶心。

有没有人有更好的主意?也许是经验之谈?

谢谢!

最佳答案

我知道您已经有了解决方案,但我想我会尝试一种不同的方法,它不需要获取大量的 mouseMoved 事件。我在代码中创建了 3 个自定义 View ,为它们添加了跟踪矩形,并将所有 mouseEntered 和 mouseExited 消息发送到执行 hitTest 以确定哪个 View 最上面的同一方法。这是窗口内容 View 的代码。

@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];

}

关于objective-c - 部分隐藏的 NSView 上的鼠标进入/退出事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9986267/

相关文章:

ios - 导航项中不支持 Swift 纯样式

ios - 带有 macos 目标的 React-Native

macos - 如何将 NSData 转换为 NSString 十六进制字符串?

iphone - 如何加载预放大的 WebView? (在 Xcode/Objective C 中)

ios - IOHIDFamily 的神秘控制台错误

ios - 使用 Firebase 从 iOS 设备上传图像 - objective-c

macos - 如何在允许多选的NSTableView中获取选中的行数据?

linux - 将 TERM 映射到支持的 ANSI 颜色代码?

swift - NSTableView 搜索后更新选定的单元格

cocoa - NSCollectionView 捏合缩放