Подтвердить что ты не робот

Как украсть штрихи от UIScrollView?

Сегодня, в мое творческое время, я провел довольно подробное исследование того, как украсть штрихи от UIScrollView и немедленно отправить их на конкретный подвью, сохраняя при этом поведение по умолчанию для остальной части прокрутки. Рассмотрите возможность использования UIPickerView внутри UITableView. Поведение по умолчанию состоит в том, что если вы перетаскиваете палец по представлению выбора, прокрутка будет прокручиваться, и представление выбора останется без изменений.

Первое, что я пробовал, - это переопределить

- (BOOL)touchesShouldCancelInContentView:(UIView *)view

и просто не разрешить UIScrollView отменять касания внутри представления picker. Это работает, но имеет неприятный побочный эффект. Вы хотите, чтобы представление выбора сразу отвечало, и вам нужно будет установить delaysContentTouches в НЕТ. Проблема заключается в том, что вы не хотите, чтобы остальная часть табличного представления реагировала немедленно, потому что если она будет видеть ячейку просмотра таблицы, она всегда будет подсвечиваться на несколько миллисекунд до начала прокрутки.

Вторая вещь, которую я пробовал, - это переопределить

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

потому что я прочитал, что представление прокрутки всегда возвращает себя, так что оно "украдет" штрихи из своих подзонов, а затем отправит их в подвью, если они не представляют интерес для представления прокрутки. Однако это не так. UIScrollView по умолчанию для реализации hitTest: withEvent: фактически возвращает subview, который должен получить прикосновение. Вместо этого он использует распознаватели жестов, чтобы перехватить штрихи.

Итак, третья вещь, которую я попытался, заключалась в том, чтобы реализовать свой собственный распознаватель жестов и заставить его потерпеть неудачу, если прикосновение было вне представления выбора и в противном случае это получилось. Затем я установил все распознаватели жестов вида прокрутки, если мой распознаватель жестов не смог использовать следующий код:

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 (?) мс. Я думаю, что я должен был бы написать подобный распознаватель, который заставит прокси-сервера просматривать прокрутки по умолчанию, чтобы сбой, и вместо того, чтобы откладывать касания, немедленно отправляет их в представление выбора. Поэтому, если кто-нибудь знает, как написать такой распознаватель, пожалуйста, дайте мне знать, и если у вас есть какое-либо другое решение проблемы, вы тоже очень приветствуете его.

Спасибо за то, что вы прочитали весь этот вопрос, и даже если вы не знаете ответа, вы все равно можете выдвинуть этот вопрос, чтобы он уделял больше внимания (надеюсь, от кого-то, кто может ответить на него). Благодарю!:)

4b9b3361

Ответ 1

Иногда вам нужно задать вопрос, прежде чем вы сможете найти ответ. У Дэна Рэя была аналогичная проблема, и он решил его с совершенно другим решением.

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    UIView* result = [super hitTest:point withEvent:event];

    if ([result.superview isKindOfClass:[UIPickerView class]])
    {
        self.scrollEnabled = NO;
    }
    else 
    {
        self.scrollEnabled = YES;    
    }
    return result;
}

Я тестировал код, и он отлично работает для меня. Тем не менее, на самом деле это не ворует прикосновения от прокрутки, поэтому, если кто-нибудь знает, как на самом деле украсть прикосновения, это будет здорово.

Источник: UIPickerView внутри UITableView.tableFooterView не получает привязки перетаскивания