mouseDragged: не передаются ли два подпредставления?

Я пишу программу, которая имеет несколько подклассов NSView (Frame) с различным содержимым, которые можно перетаскивать мышью в их супервизоре. Все представления содержат одно подпредставление, называемое contentView, которое, в свою очередь, может содержать более сложную иерархию.

Если у меня есть нередактируемый NSTextField в качестве contentView, события mouseDown: и mouseDragged: передаются в его супервизор без проблем, и перетаскивание работает нормально.

mouseDown:    ---> [NSTextField] ---> [Frame]
mouseDragged: ---> [NSTextField] ---> [Frame]

Если contentView является подклассом NSView, который, в свою очередь, содержит несколько NSTextFields, событие mouseDragged: не передается из NSTextFields в супервизор.

mouseDown:    ---> [NSTextField] ---> [subclassed NSView] ---> [Frame]
mouseDragged: ---> [NSTextField] -x-> 

Событие mouseDown: получено кадром. Щелчок в промежутках между NSTextFields и прямое перетаскивание contentView работает хорошо.

NSTextFields настраиваются в contentView следующим образом:

NSTextField *textfield = [[NSTextField alloc] initWithFrame:rect];
[textfield setBordered:NO];
[textfield setSelectable:NO];
[textfield setEditable:NO];
[textfield setTextColor:[NSColor blackColor]];
[textfield setBackgroundColor:[NSColor clearColor]];
[textfield setDrawsBackground:NO];
[textfield setAlignment:NSRightTextAlignment];
[textfield setFont:[NSFont fontWithName:@"Helvetica" size:14]];
[self addSubview:textfield];
[textfield release];

Я попытался добавить метод mouseDragged: как к подклассу NSTextField, так и к подклассу NSView, а также отказался от этого метода. Ни то, ни другое не имело значения. Проблема также существует с другими NSControls, которые находятся на том же уровне subview.

- (void)mouseDragged:(NSEvent *)theEvent
{
    [super mouseDragged:theEvent];
}

or

- (void)mouseDragged:(NSEvent *)theEvent
{
    [self.superview mouseDragged:theEvent];
}

На данный момент мне такое поведение кажется совершенно не интуитивным. Что-то мне не хватает? (Я работаю с Xcode 4.6.2 на Mountain Lion.)


person Klaus Boldt    schedule 20.04.2013    source источник


Ответы (2)


NSTextView имеет специальную обработку для мыши. Не уверен насчет NSTextField, но он может вести себя так же. Например, нет события mouseUp. Событие mouseDown входит в локальный цикл (возможно, для перетаскивания содержимого). Вы можете попытаться перезаписать mouseDown в своем классе и вызвать NSView mouseDown, чтобы обойти нажатие NSTextField мыши. См. этот вопрос SO, чтобы узнать, как это сделать.

person Mike Lischke    schedule 20.04.2013
comment
Я не уверен, что полностью понимаю этот подход. Перетаскивание работает нормально, если NSTextField является прямым подчиненным представлением NSView, выполняющего перемещение. Проблемы начнутся только в том случае, если я введу более глубокую иерархию. Кроме того, поскольку NSTextField является подклассом NSResponder, не решит ли его перезапись mouseDown / mouseDragged / mouseUp, как указано в моем исходном вопросе? - person Klaus Boldt; 21.04.2013
comment
Кажется, что если я перезаписываю mouseDown: в NSTextField и не вызываю mouseDown: в любом другом представлении из него, mouseDragged: и mouseUp: вызываются и отправляются в супервизор. Конечно, в этом случае я не могу инициировать перетаскивание. - person Klaus Boldt; 21.04.2013
comment
Я попытался реализовать ваши подсказки по ссылке, но приложение вылетело с уведомлением о том, что адрес не содержит раздела, указывающего на раздел в объектном файле. Мой код для mouseDown: Method nsviewMouseDownMethod = class_getClassMethod([NSResponder class], @selector(mouseDown:)); IMP mouseDownImplememtation = method_getImplementation(nsviewMouseDownMethod); mouseDownImplememtation(self.superview, @selector(mouseDown:)); - person Klaus Boldt; 21.04.2013

Хорошо, я нашел ответ. Это не имело ничего общего с тем, что NSTextFields отключает любые события мыши. Когда я щелкнул NSView, была вызвана процедура проверки правильности содержимого. Это освободит все подвиды и изменит макет всего вида. Это, естественно, отключило любые события перетаскивания из событий mouseDown того же подпредставления (которых больше не существовало).

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

person Klaus Boldt    schedule 21.04.2013
comment
проверка того, был ли уже активирован NSView для перетаскивания, как? - person Juanmi; 25.03.2020