Краткая
У меня проблема с UITableView
внутри UIScrollView
. Когда я прокручиваю внешний scrollView
, table
не получает событие willSelect/didSelect
при первом касании, но во втором. Что еще более странно, сама ячейка получает касания и выделенное состояние, даже если delegate
не делает.
Подробное объяснение
Моя иерархия просмотров:
UIView
- UIScrollView (outerscroll)
- Some other views and buttons
- UITableView (tableView)
Внутри просмотра прокрутки у меня есть дополнительные представления, которые расширяются/закрываются динамически. В представлении таблицы нужно "зафиксировать" сверху, вместе с некоторыми другими элементами представления, поэтому я создал этот макет, который позволяет мне легко перемещать элементы аналогичным образом, чем Apple рекомендует с помощью преобразований, когда прокрутка происходит.
Таблица View преобразуется с эффектом трансляции, когда внешняя структура перемещается следующим образом:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView == self.outerScrollView) {
CGFloat tableOffset = scrollView.contentOffset.y - self.fixedHeaderFrame.origin.y;
if (tableOffset > 0) {
self.tableView.contentOffset = CGPointMake(0, tableOffset);
self.tableView.transform = CGAffineTransformMakeTranslation(0, tableOffset);
}
else {
self.tableView.contentOffset = CGPointMake(0, 0);
self.tableView.transform = CGAffineTransformIdentity;
}
// Other similar transformations are done here, but not involving the table
}
В моей ячейке, если я реализую эти методы:
- (void)setSelected:(BOOL)selected {
[super setSelected:selected];
if (selected) {
NSLog(@"selected");
}
}
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
{
[super setHighlighted:highlighted animated:animated];
if (highlighted) {
NSLog(@"highlighted");
}
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
NSLog(@"touchesBegan");
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesEnded:touches withEvent:event];
NSLog(@"touchesEnded");
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesCancelled:touches withEvent:event];
NSLog(@"touchesCancelled");
}
Y может видеть этот вывод при сбое (первый раз):
2014-02-10 13:04:40.940 MyOrderApp[5588:70b] highlighted
2014-02-10 13:04:40.940 MyOrderApp[5588:70b] touchesBegan
2014-02-10 13:04:40.978 MyOrderApp[5588:70b] touchesEnded
И этот при работе (второй раз):
2014-02-10 13:05:30.359 MyOrderApp[5588:70b] highlighted
2014-02-10 13:05:30.360 MyOrderApp[5588:70b] touchesBegan
2014-02-10 13:05:30.487 MyOrderApp[5588:70b] touchesEnded
2014-02-10 13:05:30.498 MyOrderApp[5588:70b] expanded
Никакое другое изменение кадра, анимация или любое другое взаимодействие вида не выполняется между первым и вторым касанием. Кроме того, только при прокрутке больших объемов появляется ошибка, но с прокруткой всего в несколько пикселей все работает как ожидалось.
Я также экспериментировал с изменением некоторых свойств, но не повезло. Некоторые из вещей, которые я сделал:
- Удалите
userInteractionEnabled
из представлений, отличных от прокрутки и таблицы - Добавить вызов
setNeedsLayout
в таблицу, прокрутку и основной вид, когда происходитscrollViewDidScroll
. - Удаление преобразований из таблицы (все еще происходит)
Я видел некоторые комментарии о неожиданном поведении встраивания UITableViews
внутри UIScrollViews
, но я не вижу такого предупреждения в официальной документации Apple, поэтому я ожидаю, что он сработает.
Приложение - только iOS7 +.
Вопросы
Кто-нибудь из сталкивался с подобными проблемами? Почему это и как я могу его решить? Я думаю, что я мог бы перехватить жест нажатия на ячейку и передать его с помощью специального делегата или подобного, но Я хотел бы, чтобы таблица получала правильные события, и поэтому мой UITableViewDelegate
получает как ожидалось.
Обновления
- Я попытался отключить повторное использование ячеек, как это было предложено в комментарии, но все равно происходит так же.