将拖放事件转发到父视图

问题描述 投票:2回答:4

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

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

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

这有可能吗?不知道我是否可以用响应者链以某种方式设置它?

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

objective-c cocoa drag-and-drop nsview nsresponder
4个回答
5
投票

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

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

基本上,如果未注册视图以接收任何拖动事件,则应自动将该信息传递给其父视图。所以在我的情况下,我最终得到了这样的东西:

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

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

我希望这有帮助。


3
投票

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

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

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


0
投票

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


0
投票

仍然适用于XCode 10.1。 Swift 4.2。根据10.14.4 Beta(18E184e)。

// MARK: - ViewController lifecycle

override func viewDidLoad() {
    super.viewDidLoad()
    self.view.subviews.forEach { $0.unregisterDraggedTypes() }
}
© www.soinside.com 2019 - 2024. All rights reserved.