我有一个应用程序,我有一个自定义视图它是从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() }
}
可能有更好的方法,但您可以将拖动协议实现放在类别中,而不是直接放在视图中,并将该类别包含在每个视图中