Передача сенсорных событий в соответствующие родственные UIViews - PullRequest
12 голосов
/ 13 октября 2010

Я пытаюсь обработать сенсорные события с помощью touchesBegan в оверлее к родительскому элементу UIView, но также позволяю сенсорному вводу проходить до нижнего уровня UIView s.Я ожидал, что будет какой-то прямой способ обработать сенсорное событие и затем сказать «теперь отправьте его следующему респонденту, как если бы этого не было», но все, что я могу найти, - это метод nextResponder, которыйвозвращать родителя моему виду наложения.Тогда этот родительский объект на самом деле не передает его следующему брату этого оверлейного представления, поэтому я не уверен, как сделать то, что кажется простой задачей, которая обычно выполняется с помощью сенсорного обратного вызова, который получает значение True или False, чтобы сообщить это.продолжать ли обрабатывать иерархию виджетов.

Я что-то упускаю из виду?

Ответы [ 2 ]

3 голосов
/ 25 декабря 2011

Поздний ответ, но я думаю, вам лучше переопределить hitTest:withEvent: вместо touchesBegan.Мне кажется, что touchesBegan - это довольно «высокоуровневый» метод, который предназначен для того, чтобы просто сделать простую вещь, поэтому вы не можете изменить на этом уровне, если событие будет распространяться дальше.Правильное место для этого - hitTest:withEvent:.

Также взгляните на этот SO-ответ для получения более подробной информации об этом пункте.

1 голос
/ 01 января 2012

Я понимаю желаемое поведение, которое вы ищете, Джои - я не нашел в API чего-то такого, что поддерживало бы это автоматическое поведение при передаче сообщений по цепочке с одноуровневыми представлениями.

То, что я первоначально написал ниже, касалось просто информирования родительского UIView о прикосновении. Это по-прежнему применимо, но я считаю, что вам нужно сделать еще один шаг вперед, чтобы родительский UIView использовал технику тестирования попаданий, описанную Серхио в каждом из его подпредставлений, которые являются родственными элементами наложения, и чтобы родительский UIView вручную вызывал «do метод "что-то" на каждом из его подпредставлений, которые проходят тест на попадание. Каждое из этих родственных представлений может возвращать значение BOOL о том, прерывать ли информирование других братьев и сестер или продолжать цепочку.

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

Мой оригинальный ответ

С небольшим количеством ручной работы, вы можете соединить это вместе самостоятельно. Я должен был сделать это, и это сработало для меня, потому что у меня был часто повторяющийся вариант использования (представление наложения на кнопке), где имел смысл создавать некоторые пользовательские классы. Если ваша ситуация похожа, одного из этих методов будет достаточно.

Вариант 1: Если оверлей не должен ничего делать, но выглядит привлекательно, сделайте так, чтобы он полностью отказался от обработки с помощью userInteractionEnabled = NO. Это сделает так, чтобы сенсорное событие перешло к его родительскому UIView (тому, к которому оно относится).

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

С опцией 2 он больше подходит для простых типов UIControlEvent, таких как UIControlEventTouchDown и UIControlEventTouchUpInside. В моем случае (пользовательский подкласс UIButton с настраиваемым видом наложения поверх него) я связываю касания и подправляю события на кнопке двумя отдельными методами. Они срабатывают, если на самой кнопке происходит событие касания или касания изнутри. Но они также являются хуками, которые я могу вызвать из вида наложения, если мне нужно смоделировать, что произошло нажатие кнопки.

В зависимости от ваших потребностей, у вас может быть известный протокол между оверлеем и его родительским UIView или просто неформально тестировать оверлей UIView с проверкой respondsToSelector: перед тем, как вызывать performSelector: с помощью пользовательского метода, который вы хотите вызвал бы это автоматически, если бы UIView не был покрыт оверлеем.

...