Пересылка события перетаскивания в родительское представление

У меня есть приложение, где у меня есть один пользовательский вид, который является производным от 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() }
}

Возможно, есть лучший способ, но вы можете поместить реализацию протокола перетаскивания в категорию, а не в представление непосредственно, и включить эту категорию в каждое представление.

Другие вопросы по тегам