Хорошо, в основном у меня есть представление с серией слегка перекрывающихся подпредставлений.Когда щелкается подпредставление, оно перемещается вверх (среди прочего) по-настоящему простому двухслойному режиму:
-(void)mouseDown:(NSEvent *)theEvent {
if (_selected) { // Don't do anything this subview is already in the foreground
return;
}
NSView *superview = [self superview];
[self removeFromSuperview];
[superview addSubview:self positioned:NSWindowAbove relativeTo:nil];
}
Это прекрасно работает и кажется «нормальным» способом сделать это.
Проблема в том, что я сейчас ввожу некоторую логику перетаскивания в представление, поэтому мне нужно ответить на -mouseDragged:
.К сожалению, поскольку представление удалено из иерархии представлений и повторно добавлено в процессе, я не могу заставить представление выйти на передний план и перетаскивать его одним и тем же действием мыши.Он получает mouseDown:
, но никогда не получает mouseDragged:
или любые последующие события.Он тянется, только если я оставляю кнопку мыши и снова щелкаю на представлении, поскольку второй щелчок не делает никаких манипуляций с иерархией представлений.
Могу ли я что-нибудь сделать, что позволит представлению перейти кна переднем плане, как это, И продолжайте получать последующие события -mouseDragged:
и -mouseUp:
, которые следуют?
Я начал с мысли о том, чтобы переопределить -hitTest:
в суперпредставлении и перехватывать событие mouseDown по порядку.чтобы вывести вид на передний план до , он фактически получает событие.Проблема в том, что из -hitTest:
как мне определить тип события, для которого я на самом деле выполняю тест на попадание?Я не хотел бы перемещать подпредставление на передний план для других событий мыши, таких как mouseMoved и т. Д.
UPDATE |Я действительно сделал это, в своем супервизоре, но это похоже на действительно плохой запах кода, вызывающий событие с -hitTest:
напрямую.
-(NSView *)hitTest:(NSPoint)aPoint {
NSView *view = [super hitTest:aPoint];
if ([view isKindOfClass:[EDTabView class]] && ![(EDTabView *)view isActive]) {
// Effectively simulate two mouseDown events in sequence for this special case
[view mouseDown:nil]; // Works because I know too much about the implementation
}
return view;
}
Есть две вещи, которые кажутся неправильными в этом.Самое большое - это то, что я выполняю действие до того, как -hitTest:
даже вернулся, а затем выполняю как обработано AppKit после того, как -hitTest:
завершено.Во-вторых, у меня нет события для передачи, поэтому я передаю ноль.В этом случае это работает, так как я знаю, что обработчик событий на самом деле не обрабатывает какие-либо данные о событиях, но он не очень хорош.Альтернативой было перенести всю логику в суперпредставление, но разделение проблем здесь кажется еще хуже.
ОБНОВЛЕНИЕ |Этот -hitTest:
хак не работает ... он срабатывает, когда я не делаю щелчок мышью, например, когда я перетаскиваю что-то поверх окна просмотра.Все еще ищите хорошее решение этой проблемы.
Ответ может буквально указать, как представление может покинуть и повторно ввести свое суперпредставление во время операции перетаскивания, или (возможно, более элегантный) альтернативный способ перемещениявид на передний план, отличный от [view removeFromSuperview]; [superview addSubview:view ...];
.