gpt4 book ai didi

cocoa - 将 subview 带到 mouseDown 的顶部 : AND keep receiving events (for dragging)

转载 作者:行者123 更新时间:2023-12-03 16:27:44 26 4
gpt4 key购买 nike

好吧,基本上我有一个带有一系列稍微重叠的 subview 的 View 。单击 subview 时,它会通过非常简单的两行代码移动到顶部(除其他外):

-(void)mouseDown:(NSEvent *)theEvent {
if (_selected) { // Don't do anything this subview is already in the foreground
return;
}
NSView *superview = [self superview];
[self removeFromSuperview];
[superview addSubview:self positioned:NSWindowAbove relativeTo:nil];
}

这工作正常,似乎是执行此操作的“正常”方式。

问题是我现在向 View 引入一些拖动逻辑,因此我需要响应 -mouseDragged:。不幸的是,由于 View 已从 View 层次结构中删除并在此过程中重新添加,因此我无法让 View 到达前台并在同一鼠标操作中拖动。它接收 mouseDown:,但从不接收 mouseDragged: 或任何后续事件。仅当我松开鼠标并再次单击 View 时,它才会拖动,因为第二次单击不会进行任何 View 层次结构杂耍。

我能做些什么来让 View 像这样移动到前台,并继续接收后续的 -mouseDragged:-mouseUp: 事件接下来是什么?

我开始按照在 super View 中重写 -hitTest: 的思路并拦截 mouseDown 事件,以便在实际接收之前将 View 带到前台事件。这里的问题是,在 -hitTest: 中,我如何区分我实际执行 HitTest 的事件类型?我不想将 subview 移动到前台以执行其他鼠标事件,例如 mouseMoved 等。

更新 |我实际上已经在我的 super View 中完成了此操作,但感觉就像是直接从 -hitTest: 触发事件的非常糟糕的代码味道。

-(NSView *)hitTest:(NSPoint)aPoint {
NSView *view = [super hitTest:aPoint];
if ([view isKindOfClass:[EDTabView class]] && ![(EDTabView *)view isActive]) {
// Effectively simulate two mouseDown events in sequence for this special case
[view mouseDown:nil]; // Works because I know too much about the implementation
}
return view;
}

有两件事感觉不对。最大的问题是我在 -hitTest: 返回之前执行操作,然后在 -hitTest: 完成后按照 AppKit 的处理方式执行操作。第二个是我没有要传递的事件,所以我传递的是零。它在这种情况下有效,因为我知道事件处理程序实际上并不处理任何事件数据,但这并不是很好。另一种方法是将整个逻辑移至 super View 中,但这里的关注点分离感觉更糟。

更新 |这个 -hitTest: hack 被破坏了......当我没有单击鼠标时,例如当我将某些东西拖到 View 顶部时,它就会被触发。仍在寻找解决此问题的好方法。

答案可以从字面上指示 View 在拖动操作期间如何离开并重新进入其 super View ,或者(也许更优雅)是将 View 移动到前台的替代方法,而不是 [view removeFromSuperview ]; [superview addSubview:view ...];.

最佳答案

好吧,我一时兴起尝试了一些不合逻辑的事情。

而不是将 View 移动到前景:

[theView removeFromSuperview];
[theSuperview addSubview:theView positioned:NSWindowAbove relativeTo:nil];

我只是删除了 removeFromSuperview 行,想知道如果您尝试向 super View 添加 View 两次,AppKit 实际上会做什么(我假设它提供了防止这种情况发生的保护)。

它可以工作,至少在 Snow Leopard 下是这样,并且它解决了很多问题。正如方法名称所暗示的那样,父 View 中已经存在的 View 不会被添加,但它确实会设置其位置,而不必先将其从父 View 中删除。

关于cocoa - 将 subview 带到 mouseDown 的顶部 : AND keep receiving events (for dragging),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4574096/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com