首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果事件不处理,则将事件发送到另一个NSControl下面的NSControl

如果事件不处理,则将事件发送到另一个NSControl下面的NSControl
EN

Stack Overflow用户
提问于 2009-10-08 17:39:54
回答 2查看 2.1K关注 0票数 0

我有多个叠加的控件,可以在特定条件下处理鼠标单击。我想要做的是:

顶层控件接收到underneath.

  • This事件。顶层控件决定是否处理mouseDown:事件。如果处理了,则执行一些操作并防止其他控件接收到mouseDown:事件。<>H29H 110如果不处理,则将事件发送到属于控件的控件,以决定是否处理事件。

本质上,我试图将事件发送到其"Z-Order“位于顶部控件之下的控件,而没有顶层控件需要了解其他控件或在实例化时需要一些特殊设置。

我想到的第一件事是将事件发送给[topControl nextResponder],但似乎窗口上所有控件的nextResponder都是窗口本身,而不是像我之前所想的那样基于Z顺序的一系列控件。

有没有办法做到这一点,而不求助于手动设置下一个应答者?目标是获得一个独立于其他控件的控件,该控件只需放在窗口上并按预期工作。

提前感谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-10-08 20:34:10

很难确切知道最佳的方法,因为我不知道您的应用程序是干什么的,但是这里有一个想法。听起来你想把消息传递给视图层次结构.不知何故。

无论如何,视图可以做两件事中的一件:

  • 处理消息
  • ,将其传递给"next视图“(您如何定义”下一个视图“取决于应用程序)

所以。你会怎么做?视图的默认行为应该是将消息传递给下一个视图。实现这类事情的一个好方法是通过一个非正式的协议。

代码语言:javascript
复制
@interface NSView (MessagePassing)

- (void)handleMouseDown:(NSEvent *)event;
- (NSView *)nextViewForEvent:(NSEvent *)event;

@end

@implementation NSView (MessagePassing)

- (void)handleMouseDown:(NSEvent *)event {
    [[self nextView] handleMouseDown:event];
}

- (NSView *)nextViewForEvent:(NSEvent *)event {
    // Implementation dependent, but here's a simple one:
    return [self superview];
}

@end

现在,在应该具有这种行为的视图中,您可以这样做:

代码语言:javascript
复制
- (void)mouseDown:(NSEvent *)event {
    [self handleMouseDown:event];
}

- (void)handleMouseDown:(NSEvent *)event {
    if (/* Do I not want to handle this event? */) {
        // Let superclass decide what to do.
        // If no superclass handles the event, it will be punted to the next view
        [super handleMouseDown:event];
        return;
    }

    // Handle the event
}

您可能希望创建一个NSView子类来覆盖mouseDown:,然后将其他自定义视图类作为基础。

如果您想要根据实际的z顺序确定“下一个视图”,请记住,z顺序是由subviews集合中的顺序确定的,后面的视图首先出现。所以,你可以这样做:

代码语言:javascript
复制
- (void)nextViewForEvent:(NSEvent *)event {
    NSPoint pointInSuperview = [[self superview] convertPoint:[event locationInWindow] fromView:nil];
    NSInteger locationInSubviews = [[[self superview] subviews] indexOfObject:self];
    for (NSInteger index = locationInSubviews - 1; index >= 0; index--) {
        NSView *subview = [[[self superview] subviews] objectAtIndex:index];
        if (NSPointInRect(pointInSuperview, [subview frame]))
            return subview;
    }
    return [self superview];
}

这可能比你想要的要多,但我希望这能帮上忙。

票数 1
EN

Stack Overflow用户

发布于 2009-10-08 22:40:51

你所要做的就是打电话给[super mouseDown:event]。由于MacOSX10.5(这是而不是以前的工作方式),NSView知道如何处理重叠的视图,并将为您处理事件处理。

如果您需要在10.5:之前针对发行版,这是一个非常糟糕的主意,。事件处理机制不仅不知道如何处理重叠的子视图,绘图系统也不知道,而且您可以看到一些非常奇怪的工艺品。尽管如此,如果你下定决心:

在自定义控件/视图中重写-[NSView hitTest:]。AppKit使用此方法确定要向哪个层次结构中的哪个视图传递鼠标事件。如果您返回nil,您的自定义视图中的这个点将被忽略,并且事件应该被传递到涵盖这一点的下一个视图。

尽管如此,由于我前面概述的原因,这仍然是一个不好的主意。它当时并不是AppKit正式支持的东西,在10.4和更早版本上,更普遍接受的解决方法是使用子窗口。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1539386

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档