Сегодня в свое творческое время я провел довольно всеобъемлющее исследование о том, как украсть касания из UIScrollView и мгновенно отправить их в конкретное подпредставление, сохраняя при этом поведение по умолчанию для остальной части представления прокрутки. Рассмотрите возможность использования UIPickerView внутри UITableView. Поведение по умолчанию состоит в том, что, если вы проведете пальцем по виду средства выбора, представление прокрутки будет прокручиваться, и представление средства выбора останется неизменным.
Первым делом я попытался переопределить
- (BOOL)touchesShouldCancelInContentView:(UIView *)view
и просто не разрешать UIScrollView отменять касания в представлении выбора. Это работает, но имеет неприятный побочный эффект. Вы хотите, чтобы окно выбора отвечало незамедлительно, и поэтому вам придется установить delaysContentTouches
на NO. Проблема в том, что вы не хотите, чтобы остальная часть табличного представления реагировала немедленно, потому что если это произойдет, ячейка табличного представления будет всегда подсвечиваться в течение нескольких миллисекунд до начала прокрутки.
Второе, что я попробовал, это переопределить
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
потому что я прочитал, что представление прокрутки всегда возвращает себя, так что оно «украдет» прикосновения из своих подпредставлений и позже отправит их в подпредставление, если они не были интересны представлению прокрутки. Однако это уже не так. Реализация по умолчанию hitTest: withEvent: UIScrollView по умолчанию возвращает подпредставление, которое должно получить прикосновение. Вместо этого он использует распознаватели жестов для перехвата касаний.
Итак, третье, что я пытался сделать, - это внедрить свой собственный распознаватель жестов и вызвать его сбой, если касание находилось за пределами окна выбора и, в противном случае, было успешным. Затем я установил все распознаватели жестов представления прокрутки на сбой, если мой распознаватель жестов не смог использовать следующий код:
for (UIGestureRecognizer * gestureRecognizer in self.tableView.gestureRecognizers)
{
[gestureRecognizer requireGestureRecognizerToFail:myRecognizer];
}
Это на самом деле крадет прикосновения от вида прокрутки, но вид сборщика никогда не получает их. Поэтому я подумал, что, возможно, я мог бы просто отправить все штрихи, которые мой распознаватель жестов получил, используя этот код:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
for (UITouch *touch in touches)
[touch.view touchesBegan:touches withEvent:event];
}
Приведенный выше код является упрощенной версией. Я также удостоверяюсь, что представление является представлением выбора (или одним из его подпредставлений) и устанавливаю соответствующее состояние для распознавателя жестов, как я упоминал выше. Я также сделал то же самое для отмененного, закончил и переехал. Тем не менее, представление выбора все еще не отвечает.
Я также попробовал еще одну вещь, прежде чем вернуться к своей обычной работе. Во время моего обширного поиска в Google я прочитал, что вложенные UIScrollViews волшебным образом работают с 3.x, поэтому я попытался поместить свое представление выбора во вложенный UIScrollView и установить для него следующие свойства:
scrollView.delaysContentTouches = NO;
scrollView.canCancelContentTouches = NO;
Как и следовало ожидать, внешний вид прокрутки не обрабатывал внутренний вид прокрутки так же, как он обрабатывал вид выбора, поэтому внутренний вид прокрутки не принимал прикосновения. Я думал, что это был длинный выстрел, но его было достаточно просто реализовать, поэтому я подумал, что стоит попробовать.
Что я знаю, так это то, что в UIScrollView есть распознаватель жестов с именем UIScrollViewDelayedTouchesBeganGestureRecognizer
, который перехватывает прикосновения и отправляет их в соответствующее подпредставление через 150 (?) Мс. Я думаю, что я должен быть в состоянии написать аналогичный распознаватель, который вызывает сбой распознавателей по умолчанию представления прокрутки и вместо того, чтобы откладывать касания немедленно отправляет их в представление выбора. Поэтому, если кто-то знает, как написать такой распознаватель, пожалуйста, дайте мне знать, и если у вас есть какое-либо иное решение проблемы, вы также можете поделиться этим.
Спасибо за то, что прочитали весь вопрос, и даже если вы не знаете ответа, вы все равно можете поддержать вопрос так, чтобы он получил больше внимания (надеюсь, от кого-то, кто может ответить на него). Спасибо! :)