2

我有一个应用程序,其中有一个从 NSView 派生的自定义视图。在这个视图中,有几个自定义的子视图,它们也是从 NSView 派生的。

我想实现允许将 URL 拖放到视图上的拖放行为。一切都已经为主视图工作了。

所以,实际上我必须在子视图和父视图类上实现拖动行为处理程序。问题是,我不想将完整的处理代码复制到所有子视图以使它们也接受拖动事件。所以我认为这将是让他们将所有拖动事件转发到父视图的最佳方式。

这有可能吗?不确定我是否可以通过响应者链以某种方式进行设置?

任何提示都非常感谢!提前致谢。

4

4 回答 4

6

我遇到了类似的问题,我希望视图中删除任何内容,或者视图处理它的任何子视图,但调用从未到达那里。

经过一些研究,我发现这个答案是最有帮助的:https ://stackoverflow.com/a/7389711/327471

本质上,如果一个视图没有注册来接收任何拖动事件,它应该自动将该信息传递给它的父视图。所以就我而言,我最终得到了这样的结果:

NSArray *subviews = [self.view subviews];
for (NSView *aSubview in subviews) {
    [aSubview unregisterDraggedTypes];
}

当然,您可以比这更精确,并确保只检查某种类型的子类或您想要的任何参数。但最终关键是从它的拖动类型中取消注册问题子视图。

我希望这有帮助。

于 2012-01-09T02:29:03.957 回答
2

如果子视图仅用于显示并且不需要任何用户交互,则可以-hitTest:在父视图中覆盖,如下所示:

- (NSView *)hitTest:(NSPoint)aPoint
{
    NSView* hitView = [super hitTest:aPoint];
    if(hitView)
        return self;
    return nil;
}

这使得父视图接收所有鼠标事件。

于 2011-11-25T00:42:32.427 回答
1

XCode 10.1 仍然有效。斯威夫特 4.2。在 10.14.4 Beta (18E184e) 下。

// MARK: - ViewController lifecycle

override func viewDidLoad() {
    super.viewDidLoad()
    self.view.subviews.forEach { $0.unregisterDraggedTypes() }
}
于 2019-02-15T16:17:46.950 回答
-1

可能有更好的方法,但您可以将拖动协议实现放在一个类别中,而不是直接放在视图中,并将该类别包含在每个视图中。

于 2012-01-09T02:58:57.360 回答