将拖放事件转发到父视图



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

我想实现一个拖放行为,允许url被拖放到视图上。一切都已经为主视图工作了。

因此,实际上我需要在子视图和父视图类上实现拖动行为处理程序。问题是,我不想将完整的处理代码复制到所有子视图中,以使它们也接受拖动事件。所以我认为最好的方法就是让他们把所有的拖动事件转发到父视图

这是可能的吗?不确定我是否可以用响应链来设置这个?

任何提示都非常感谢!!

我遇到过一个类似的问题,我想在视图中删除任何东西,或者它的任何子视图由视图处理,但调用从未到达那里。

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

本质上,如果一个视图没有注册接收任何拖动事件,它应该自动将该信息传递给它的父视图。所以在我的例子中,我最终写成了这样的内容:

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

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

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

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

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

仍然适用于XCode 10.1。斯威夫特4.2。10.14.4 Beta (18E184e).

// MARK: - ViewController lifecycle
override func viewDidLoad() {
    super.viewDidLoad()
    self.view.subviews.forEach { $0.unregisterDraggedTypes() }
}

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

最新更新