Как я могу обнаружить события касания в UIImageView внутри глубокой иерархии UIView?

Я разрабатываю простую игру на iPhone и начал с приложения, основанного на представлении, и через UIViewController я загружаю пользовательское UIView, которое содержит еще несколько UIView и несколько UIImageView. Я хочу обнаружить сенсорные события на некоторых UIImageView, но пока не смог.

Я создал второй проект для целей тестирования и понял, что UIImageViews обрабатывают сенсорные события, когда иерархия выглядит так:

UIViewController -> UIView -> UIImageView,

но когда это так:

UIViewController -> UIView -> UIView -> UIImageView

они не обнаружены.

Примечания:
- userInteractionEnabled равно YES во всех случаях
- все UIViews и UIImageViews, упомянутые выше, являются пользовательскими подклассами.

Можете ли вы придумать какую-либо причину, по которой, когда пользовательский UIImageView становится глубже в иерархии представлений, он не может получать события касания?


person jester    schedule 30.03.2010    source источник


Ответы (1)


Прикосновения идут к месту назначения длинным и окольным путем. Официально они идут вверх по цепочке респондентов, которая начинается с первого респондента, а затем идет от самого глубокого представления, включающего касание, к его контроллеру представления, к следующему представлению, включающему касание, и т. д.

Но реальная картина еще более сложна, так как при поиске представления с самым глубоким касанием, к которому можно перейти, касание, по сути, «запрашивает» эту информацию у представления самого высокого уровня, вызывая метод hitTest:withEvent:. Это позволяет некоторым суперпредставлениям перехватывать касания, что может быть очень полезно, как в UIScrollView, который иногда что-то делает (прокручивает/масштабирует), прежде чем его подвиды узнают, что происходит.

Вот несколько советов, которые помогут определить, почему представление может не реагировать на прикосновения:

  • Переопределить [hitTest:withEvent:]1 для каждого из ваших просмотров и NSLog при попадании в них, чтобы увидеть, кто рассматривается для цепочки респондеров.
  • Используйте недокументированный метод (и, следовательно, возьмите его перед отправкой) UIView recursiveDescription для проверки кадров всех представлений во время выполнения. Виды по умолчанию отображаются за пределами своих размеров кадра, поэтому они могут выглядеть нормально, но логически иметь меньшие размеры, чем визуально, и касания реагируют на основе логических (не визуальных) размеров.
  • Это может показаться глупым, но дважды проверьте, правильно ли ваши методы связаны с искомым выходом. Например, если вы ожидаете, что ваш метод [MyClass buttonPressed] будет вызываться при касании UIButton, дважды проверьте, добавили ли вы свой экземпляр MyClass и @selector(buttonPressed) в качестве пары цель/действие для этой кнопки.
  • Если ни один из них не работает, переопределите touchesBegan:withEvent: сообщениями NSLog, чтобы увидеть, где касания идут вверх по цепочке респондентов.

И вы это уже знаете, но следите за флагом userInteractionEnabled!

Надеюсь, этого достаточно, чтобы изолировать проблему.

person Tyler    schedule 30.03.2010
comment
Прежде всего спасибо за быстрый ответ! У меня как раз было время ознакомиться с вашими советами. Проблема заключалась в том, что я не инициализировал UIImageView с помощью initWithFrame. Это был ваш второй совет, который заставил меня заподозрить, что проблема именно в этом: по умолчанию изображения отображаются за пределами размеров кадра, поэтому они могут выглядеть нормально, но логически имеют меньшие размеры, чем визуально, и касания реагируют на основе логического (не визуального) ) размеры. - person jester; 01.04.2010