Перекрестные указатели UIScrollViews - Могу ли я изменить поведение прокрутки?
Здесь, как работают представления прокрутки:. Один вид прокрутки - пейджинг включен в горизонтальном направлении. Каждая "страница" этого прокрутки содержит вертикальный прокручиваемый UITableView. Без изменений это работает нормально, но не идеально.
Неправильное поведение:. Когда пользователь прокручивается вверх и вниз по представлению таблицы, но затем быстро перебирается на следующую страницу, горизонтальный щелчок/салфетка не будет работать вначале - он не будет работать, пока стол не будет неподвижен (даже если салфетка очень четко горизонтальная).
Как это должно работать: Если ярлык явно горизонтальный, мне бы хотелось, чтобы страница изменилась, даже если представление таблицы все еще прокручивается/отскакивает, так как это то, что пользователь будет ожидать слишком,
Как я могу изменить это поведение - самый простой или лучший способ?
ПРИМЕЧАНИЕ По различным причинам UIPageViewController, как указано в некоторых ответах, не будет работать. Как я могу это сделать с помощью кросс-направленных UIScrollViews (/one - это табличное представление, но вы получаете идею)? Я несколько часов стучал головой о стену - если вы думаете, что можете это сделать, я буду более чем счастливо награждать щедростью.
Ответы
Ответ 1
По моему пониманию вопроса, только во время прокрутки tableView мы хотим изменить поведение по умолчанию. Все остальные действия будут одинаковыми.
SubClass UITableView
. UITableView
являются подклассом UIScrollView
s. В подклассе UITableView
реализуем один метод UIScrollView
UIGestureRecognizer
delegate
- (BOOL)gestureRecognizer:(UIPanGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UISwipeGestureRecognizer *)otherGestureRecognizer
{
//Edit 1
//return self.isDecelerating;
//return self.isDecelerating | self.bounces; //If we want to simultaneous gesture on bounce and scrolling
//Edit 2
return self.isDecelerating || self.contentOffset.y < 0 || self.contentOffset.y > MAX(0, self.contentSize.height - self.bounds.size.height); // @Jordan edited - we don't need to always enable simultaneous gesture for bounce enabled tableViews
}
Поскольку мы хотим изменить поведение жестов по умолчанию, пока tableView замедляется.
Теперь измените весь класс UITableView на только что созданный tableViewSubClass и запустите проект, а салфетки должны работать, пока выполняется прокрутка таблицыView.:]
Но прокрутка выглядит слишком чувствительной, в то время как TableView прокручивается. Пусть сделайте салфетки немного ограничительными.
SubClass UIScrollView
. В подклассе UIScrollView
реализуйте еще один метод UIGestureRecognizer
delegate gestureRecognizerShouldBegin:
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
CGPoint velocity = [(UIPanGestureRecognizer *)gestureRecognizer velocityInView:self];
if (abs(velocity.y) * 2 < abs(velocity.x)) {
return YES;
}
}
return NO;
}
Мы хотим, чтобы "салфетка была четко горизонтальной". Выше кода разрешает только жест, если скорость движения по оси x вдвое больше, чем на оси y. [Не стесняйтесь увеличивать жестко закодированное значение "2", если хотите. Чем выше значение, тем более важным является салфетка.]
Теперь измените класс `UiScrollView '(который имеет несколько TableViews) на ваш ScrollViewSubClass. Запустите проект.:]
![enter image description here]()
Я сделал проект на gitHub https://github.com/rishi420/SwipeWhileScroll
Ответ 2
![enter image description here]()
Хотя яблоку не нравится этот метод слишком много:
Важно: вы не должны встраивать объекты UIWebView или UITableView в объекты UIScrollView. Если вы это сделаете, может возникнуть непредвиденное поведение потому что события касания для двух объектов могут быть смешаны и ошибочно обрабатываются.
Я нашел отличный способ выполнить это.
Это полное решение проблемы. Чтобы прокрутить UIScrollView
, пока ваша прокрутка UITableView
, вам нужно отключить взаимодействие, которое у вас есть.
- (void)viewDidLoad
{
[super viewDidLoad];
_myScrollView.contentSize = CGSizeMake(2000, 0);
data = [[NSMutableArray alloc]init];
for(int i=0;i<30;i++)
{
[data addObject:[NSString stringWithFormat:@"%d",i]];
}
UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
[self.view addGestureRecognizer:tap];
}
- (void)handleTap:(UITapGestureRecognizer *)recognizer
{
[_myTableView setContentOffset:_myTableView.contentOffset animated:NO];
}
- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView
{
scrollView.userInteractionEnabled = NO;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
scrollView.userInteractionEnabled = YES;
}
Чтобы суммировать код выше, если прокрутка UITableView
, установите userInteractionEnabled
на NO
, чтобы UIScrollView
обнаружил проведите пальцем по экрану. Если UITableView
прокручивается, и пользователь нажимает на экран, userInteractionEnabled
будет установлен на YES.
Ответ 3
Вместо использования UIScrollView
в качестве контейнера для этих представлений нескольких таблиц попробуйте использовать UIPageViewController
.
Вы можете даже интегрировать это в существующую настройку контроллера просмотра как child view controller
(непосредственно заменяя UIScrollView
).
Кроме того, вы, вероятно, захотите реализовать требуемые методы из UIPageViewControllerDataSource
и, возможно, один или несколько методов из UIPageViewControllerDelegate
.
Ответ 4
Пробовали ли вы методы: directionalLockEnabled
вашей таблицы и прокрутки и устанавливали их горизонтально для одного и вертикально для другого?
Изменить:
1)
То, что вы хотите сделать, очень усложняется, так как прикосновение ждет некоторое время (например, 0.1s), чтобы узнать, каково будет ваше движение. И если ваш стол движется, он немедленно примет ваше прикосновение к чему бы то ни было (потому что он предположительно должен реагировать на него).
Я не вижу другого решения для вас, кроме как отменить движение касания с нуля, чтобы немедленно обнаружить тот способ передвижения, который вы хотите (например, если движение будет горизонтальным), но будет более чем трудно сделать это хорошо.
2)
Еще одно решение, которое я могу вам посоветовать, состоит в том, чтобы сделать ваш стол левым и правым краем, где вы можете коснуться родительского прокрутки (например, страницы), а затем даже если ваша таблица прокручивается, если вы коснетесь здесь, будет затронут только ваш прокрутка пейджинга, Это проще, но не может вписаться в ваш дизайн, возможно...
Ответ 5
Используйте UIPageViewController
и в методе -viewDidLoad
(или любой другой метод, который наилучшим образом соответствует вашим потребностям или дизайну) получите UIPageViewController
UIScrollView
subview и назначьте ему делегат. Имейте в виду, что его свойство делегирования не будет равно нулю. Поэтому, возможно, вы можете назначить его другой ссылке, а затем присвоить ей свой объект, который соответствует UIScrollViewDelegate
. Например:
id<UIScrollViewDelegate> originalPageScrollViewDelegate = ((UIScrollView *)[pageViewController.view.subviews objectAtIndex:0]).delegate;
[((UIScrollView *)[pageViewController.view.subviews objectAtIndex:0]) setDelegate:self];
Чтобы вы могли легко реализовать методы UIScrollViewDelegate
. И ваш UIPageViewController
вызовет ваш делегат -scrollViewDidScroll:
.
Кстати, вам может потребоваться сохранить оригинальный делегат и ответить на методы делегирования с этим объектом. Вы можете увидеть пример реализации в классе ViewPagerController
в моем проекте управления пользовательским интерфейсом здесь
Ответ 6
В последнее время я столкнулся с тем же. Мой UIScrollview
находился в режиме подкачки, и каждая страница содержала UITableView
и, как вы описали, она работала, но не так, как вы ожидали, что она сработает. Вот как это удалось.
Сначала я отключил прокрутку UIScrollview
Затем я добавил UISwipeGestureRecognizer
к фактическому UITableView
для левого и правого прокрутки.
Действие для этих ударов было:
[scroll setContentOffset:CGPointMake(currentPointX + 320, PointY) animated:YES];
//Or
[scroll setContentOffset:CGPointMake(currentPointX - 320 , PointY) animated:YES];
Это работает безупречно, единственная нижняя сторона заключается в том, что если пользователь тащит свой палец на UITableView
, который будет считаться салфеткой. Он не сможет видеть половину экрана A и половину экрана B на одном экране.
Ответ 7
Вы можете подклассировать свой вид прокрутки и представления в таблице и добавить этот метод делегирования распознавателя жестов к каждому из них...
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:
(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
Я не могу быть уверен, что это именно то, что вам нужно, но оно может приблизиться.