我有多个叠加的控件,可以在特定条件下处理鼠标单击。我想要做的是:
顶层控件接收到underneath.
mouseDown:事件。如果处理了,则执行一些操作并防止其他控件接收到mouseDown:事件。<>H29H 110如果不处理,则将事件发送到属于控件的控件,以决定是否处理事件。本质上,我试图将事件发送到其"Z-Order“位于顶部控件之下的控件,而没有顶层控件需要了解其他控件或在实例化时需要一些特殊设置。
我想到的第一件事是将事件发送给[topControl nextResponder],但似乎窗口上所有控件的nextResponder都是窗口本身,而不是像我之前所想的那样基于Z顺序的一系列控件。
有没有办法做到这一点,而不求助于手动设置下一个应答者?目标是获得一个独立于其他控件的控件,该控件只需放在窗口上并按预期工作。
提前感谢!
发布于 2009-10-08 20:34:10
很难确切知道最佳的方法,因为我不知道您的应用程序是干什么的,但是这里有一个想法。听起来你想把消息传递给视图层次结构.不知何故。
无论如何,视图可以做两件事中的一件:
所以。你会怎么做?视图的默认行为应该是将消息传递给下一个视图。实现这类事情的一个好方法是通过一个非正式的协议。
@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现在,在应该具有这种行为的视图中,您可以这样做:
- (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集合中的顺序确定的,后面的视图首先出现。所以,你可以这样做:
- (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];
}这可能比你想要的要多,但我希望这能帮上忙。
发布于 2009-10-08 22:40:51
你所要做的就是打电话给[super mouseDown:event]。由于MacOSX10.5(这是而不是以前的工作方式),NSView知道如何处理重叠的视图,并将为您处理事件处理。
如果您需要在10.5:之前针对发行版,这是一个非常糟糕的主意,。事件处理机制不仅不知道如何处理重叠的子视图,绘图系统也不知道,而且您可以看到一些非常奇怪的工艺品。尽管如此,如果你下定决心:
在自定义控件/视图中重写-[NSView hitTest:]。AppKit使用此方法确定要向哪个层次结构中的哪个视图传递鼠标事件。如果您返回nil,您的自定义视图中的这个点将被忽略,并且事件应该被传递到涵盖这一点的下一个视图。
尽管如此,由于我前面概述的原因,这仍然是一个不好的主意。它当时并不是AppKit正式支持的东西,在10.4和更早版本上,更普遍接受的解决方法是使用子窗口。
https://stackoverflow.com/questions/1539386
复制相似问题