I have an application where I have one custom view which is derived from NSView.
Within this view, there are several custom subviews, which are also derived from NSView.
I want to implement a drag and drop behavior which allows URLs to be dropped onto the views. Everything is already working for the main view.
So, actually I would have to implement dragging behavior handlers on the child-views and the parent-view class.
The thing is, that I don't want to copy the complete handling code to all the child-views to make them also accept drag events. So I thought that it would be the best way to just let them forward all drag events to the parent view.
Is this possible somehow?? Not sure if I can somehow set this up with the responder-chain maybe?
Any tips are highly appreciated!!
Thanks in advance.
I faced a similar issue where I wanted anything dropped in a view, or any of it's subviews to be processed by the view, but the calls never got there.
After some research I found this answer to be the most helpful: https://stackoverflow.com/a/7389711/327471
Essentially if a view is not registered to receive any drag events it should pass that information up to it's parent view automatically. So in my case I ended up with something like this:
NSArray *subviews = [self.view subviews];
for (NSView *aSubview in subviews) {
[aSubview unregisterDraggedTypes];
}
Of course you can be more precise than that, and make sure to only check subclasses of a certain type or whatever parameters you want. But ultimately the key was unregistering the problem subview from it's dragged types.
I hope this helps.
If the subviews are used for display only and don't require any user interaction, you can override -hitTest:
in the parent view like so:
- (NSView *)hitTest:(NSPoint)aPoint
{
NSView* hitView = [super hitTest:aPoint];
if(hitView)
return self;
return nil;
}
This makes the parent view receive all mouse events.
There's probably a better way, but you could put your dragging protocol implementation in a category, rather than in the view directly, and include that category in each of the views.
Still works XCode 10.1. Swift 4.2. under 10.14.4 Beta (18E184e).
// MARK: - ViewController lifecycle
override func viewDidLoad() {
super.viewDidLoad()
self.view.subviews.forEach { $0.unregisterDraggedTypes() }
}