Невозможно прокручивать вверх/вниз и прокручивать влево/вправо одновременно с UITableView в UIScrollView

2-е обновление Благодаря комментарию @Segev и ссылке на другую тему, я смог улучшить демонстрацию чтобы заставить его в основном делать то, что я хотел. Тем не менее, это все еще не так гладко, как реализация Instagram, и мне было интересно, знает ли кто-нибудь, как я мог бы улучшить его, чтобы он стал более плавным? Кроме того, я заметил, что иногда (в моей демонстрации), когда я прокладываю влево/вправо очень быстро, и я хочу переключиться на прокрутку вверх/вниз, он все равно продолжит прокручивать влево/вправо, пока я не остановлю прокрутку и не позволяю сначала остановитесь.

Обновление:. Мне удалось заставить представление таблицы прокручивать влево/вправо после остановки прокрутки вверх/вниз путем наследования из UIScrollView и реализации методов shouldRecognizeSimultaneousWithGestureRecognizer и shouldBeRequiredToFailByGestureRecognizer из UIGestureRecognizerDelegate. Моя идея состояла в том, чтобы вернуть true в shouldRecognizeSimultaneousWithGestureRecognizer, если пользователь прокручивает вверх/вниз по таблицеView, а затем в shouldBeRequiredToFailByGestureRecognizer, чтобы вывести из строя жест вверх/вниз таблицы.

Но я все еще не могу понять, как позволить пользователю прокручивать вверх/вниз или влево/вправо после остановки начального прокрутки вверх/вниз (и палец пользователя все еще находится на устройстве).

Я создал образец проекта здесь https://github.com/paulsfds/TableViewsInScrollView. Вы можете протестировать это, прокручивая один раз на столе, затем отпустите свой палец и, пока он все еще прокручивается, верните свой палец, чтобы остановить прокрутку. Пока ваш палец все еще находится на столе, попробуйте прокрутить влево/вправо, и он должен работать. Но с этой реализацией, если вы попытаетесь несколько раз пронести по экрану таблицы, она иногда застревает, потому что будет думать, что вы пытаетесь пронести влево/вправо. Любые идеи?

Оригинал: У меня есть пара UITableViews, которые находятся в UIScrollView с включенным пейджингом и настраиваются, чтобы позволить мне оставлять страницу влево и вправо, чтобы одновременно отображался только один UITableView. Вот диаграмма (взята из Конфликтная прокрутка по UITableView в UIScrollView)

                                 +--visible area--+  ---+
+---------`UIScrollView`---------+---------------+|  --+|
| +-------------+ +-------------+|+-------------+||  -+||
| |      0      | |      1      |||      2      |||   |||
| |`UITableView`| |`UITableView`|||`UITableView`|||  equal height
| |             | |             |||             |||   |||
| +-------------+ +-------------+|+-------------+||  -+||
+--------------------------------+---------------+|  --+| 
                                 +----------------+  ---+

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

TL; DR В принципе, я не могу прокручивать вверх/вниз по таблице и прокручивать влево/вправо в представлении прокрутки одновременно, но я хотел бы иметь возможность сделать это. Пример этого будет в приложении Instagram iOS на вкладке Activity. Вы можете прокручивать вниз, а затем прокручивать вправо, пока просмотр таблицы все еще прокручивается.

Ответ 2

К сожалению, Apple не поддерживает внедрение UITableViews внутри UIScrollViews:

https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIWebView_Class/index.html

ВАЖНО

Вам не следует вставлять объекты UIWebView или UITableView в UIScrollView объекты. Если вы это сделаете, это может привести к неожиданному поведению, поскольку события для двух объектов могут быть перемешаны и неправильно обработаны.

Однако, с учетом сказанного, все еще возможно достичь того, что вы ищете. Пробовали ли вы настройку delayContentTouches на true, чтобы scrollview отправил свой неудачный прокрученный жест (например, горизонтальный прокрутки) своим дочерним элементам (т.е. Ваш табличный вид)?

self.yourScrollView.panGestureRecognizer.delaysTouchesBegan = true

Ответ 3

Хотя этот вопрос имеет принятый ответ, я хотел бы предоставить собственное решение для других, у кого могут быть подобные проблемы:

Используйте UICollectionView для отображения UITableViews вместо UIScrollView

Основные шаги с использованием UIStoriesboards:

  • Добавить UICollectionView в UIViewController в раскадровке.
  • Обновите атрибуты UICollectionView, чтобы использовать пейджинг вместо прокрутки и задайте атрибуты макета, чтобы ячейка взяла полный размер UICollecionView.
  • Добавить UITableView в UICollectionViewCell.
  • Добавьте IBOulet для UICollectionView в ViewController.h и подключите розетку.
  • Создайте подкласс UICollectionViewCell и добавьте IBOutlet в UITableView в ячейку .h
  • В вашей раскадровке задайте тип класса UICollectionViewCell для созданной пользовательской ячейки.
  • Подключите IBOutlets для UICollectionView и UITableView.
  • Наконец, вам нужно будет установить ваши делегаты и источники данных для этих двух и реализовать методы. Поскольку я попробовал это как быстрый пример, я сделал свой ViewController делегатом и источником данных как для UICollectionView, так и для UITableView. Однако ваша реализация может отличаться от этого.

До тех пор, пока вы правильно настроите свой источник данных UICollectionView, он должен выглядеть просто отлично.

Ответ 4

Я только что сделал что-то с аналогичной функциональностью.

Для меня было разработано расширение для UIPanGestureRecognizer (я работаю с быстрым 2, если вы хотите переписать решение для objC), поэтому я могу узнать, когда пользователь вытащил палец из устройства, Тогда вы можете пронести влево/вправо, я полагаю.

Вот код, я объясню это ниже:

расширение UIPanGestureRecognizer {

public override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent) {
    state = .Ended
    NSNotificationCenter.defaultCenter().postNotification(NSNotification(name: "panningEnded", object: nil))
}

}

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

С уважением