UIMenuController и цепочка респондентов: что происходит?

Я использую UIMenuController в пользовательском подклассе UIView. Это означает, что он может стать первым ответчиком и заявить об этом canPerformAction в действии «удалить».

Я также хотел бы, чтобы супервизор этого представления (также настраиваемый UIView) мог использовать контроллер меню, поэтому в этом супервизоре я пометил его как способный быть первым ответчиком и реализовал canPerformAction для различных действий («копировать» и "вырезать" в данном случае).

Вот в чем дело: когда я делаю меню видимым из (первого) подпредставления, оно помещает в меню все три действия: удалить, скопировать и вырезать. В отладчике я вижу, что canBecomeFirstResponder и canPerformAction вызываются в обоих представлениях до появления меню.

Что тут происходит? Почему контроллер меню не ограничен представлением, которое стало первым ответчиком? Или я не правильно диагностирую?

Спасибо.


person Ben Zotto    schedule 04.10.2011    source источник


Ответы (1)


Какой код вы используете?

В документации для canPerformAction:withSender:,

Эта реализация этого метода по умолчанию возвращает YES, если класс респондента реализует запрошенное действие, и вызывает следующий респондент, если это не так. ... Обратите внимание, что если ваш класс возвращает NO для команды, другой ответчик, находящийся дальше по цепочке ответчиков, может по-прежнему возвращать YES, разрешая команду.

Это кажется противоречивым, говоря, что реализация по умолчанию рекурсивно поднимается по цепочке респондентов, но также и то, что UIMenuController рекурсивно поднимается по цепочке респондентов, если вы возвращаете NO.

Самая простая уловка, вероятно, состоит в том, чтобы переопределить -nextResponder для возврата nil, но это может иметь и другие побочные эффекты (например, действия с целью «nil» по умолчанию идут вверх по цепочке респондентов!).

person tc.    schedule 04.10.2011
comment
Что ж, это объясняет. Спасибо. Я не осознавал, что цепочка респондентов использовалась именно таким образом. Похоже, достаточно просто обернуть логику canPerformAction:withSender в условное выражение в зависимости от того, активно это подпредставление или нет. Странно, но не слишком больно. Спасибо за указание на это! - person Ben Zotto; 04.10.2011