Пересылка события перетаскивания в родительское представление
У меня есть приложение, где у меня есть один пользовательский вид, который является производным от NSView. В этом представлении есть несколько пользовательских подпредставлений, которые также являются производными от NSView.
Я хочу реализовать поведение перетаскивания, которое позволяет URL-адреса быть сброшены на представления. Все уже работает на основной вид.
Итак, на самом деле мне нужно было бы реализовать обработчики перетаскивания поведения для дочерних представлений и класса родительского представления. Дело в том, что я не хочу копировать полный код обработки во все дочерние представления, чтобы они также принимали события перетаскивания. Поэтому я подумал, что это будет лучший способ просто переслать им все события перетаскивания в родительское представление.
Возможно ли это как-то?? Не уверен, смогу ли я как-то настроить это с цепочкой респондента, может быть?
Любые советы высоко ценятся! Заранее спасибо.
3 ответа
Я столкнулся с аналогичной проблемой, когда я хотел, чтобы что-то пропущено в представлении, или любое из его подпредставлений было обработано представлением, но вызовы так и не были получены.
После некоторых исследований я нашел этот ответ наиболее полезным: /questions/43284175/nsview-subviews-preryivaya-operatsiyu-peretaskivaniya/43284180#43284180
По сути, если представление не зарегистрировано для получения каких-либо событий перетаскивания, оно должно автоматически передавать эту информацию в родительское представление. Так что в моем случае я получил что-то вроде этого:
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 бета (18E184e).
// MARK: - ViewController lifecycle
override func viewDidLoad() {
super.viewDidLoad()
self.view.subviews.forEach { $0.unregisterDraggedTypes() }
}
Возможно, есть лучший способ, но вы можете поместить реализацию протокола перетаскивания в категорию, а не в представление непосредственно, и включить эту категорию в каждое представление.