Here's how the scroll views work: One scroll view is paging enabled in the horizontal direction. Each 'page' of this scroll view contains a vertically scrolling UITableView. Without modification, this works OK, but not perfectly.
The behaviour that's not right: When the user scrolls up and down on the table view, but then wants to flick over to the next page quickly, the horizontal flick/swipe will not work initially - it will not work until the table view is stationary (even if the swipe is very clearly horizontal).
How it should work: If the swipe is clearly horizontal, I'd like the page to change even if the table view is still scrolling/bouncing, as this is what the user will expect too.
How can I change this behaviour - what's the easiest or best way?
NOTE For various reasons, a UIPageViewController as stated in some answers will not work. How can I do this with cross directional UIScrollViews (/one is a table view, but you get the idea)? I've been banging my head against a wall for hours - if you think you can do this then I'll more than happily award a bounty.
Although apple doesn't like this method too much:
I've found a great way to accomplish this.
This is a complete solution for the problem. In order to scroll the
UIScrollView
while yourUITableView
is scrolling you'll need to disable the interaction you have it.To sum up the code above, if the
UITableView
is scrolling, setuserInteractionEnabled
toNO
so theUIScrollView
will detect the swipe. If theUITableView
is scrolling and the user taps on the screen,userInteractionEnabled
will be set to YES.According to my understanding of the question, it is only while the tableView is scrolling we want to change the default behaviour. All the other behaviour will be the same.
SubClass
UITableView
.UITableView
s are subClass ofUIScrollView
s. On theUITableView
subClass implement oneUIScrollView
'sUIGestureRecognizer
's delegate methodAs we only want to change the default gesture behaviour while the tableView is decelerating.
Now change all 'UITableView's class to your newly created tableViewSubClass and run the project, swipe should work while tableView is scrolling. :]
But the swipe looks a little too sensitive while tableView is scrolling. Let's make the swipe a little restrictive.
SubClass
UIScrollView
. On theUIScrollView
subclass implement anotherUIGestureRecognizer
's delegate methodgestureRecognizerShouldBegin:
We want to make the "swipe is clearly horizontal". Above code only permits gesture begin if the gesture velocity on x axis is double than on y axis. [Feel free to increase the hard coded value "2" if your like. The higher the value the swipe needs to be more horizontal.]
Now change the `UiScrollView' class (which has multiple TableViews) to your ScrollViewSubClass. Run the project. :]
I've made a project on gitHub https://github.com/rishi420/SwipeWhileScroll
You could subclass your scroll view and your table views, and add this gesture recognizer delegate method to each of them...
I can't be sure this is exactly what you are after, but it may come close.
Use
UIPageViewController
and in the-viewDidLoad
method (or any other method what best suits your needs or design) getUIPageViewController
'sUIScrollView
subview and assign a delegate to it. Keep in mind that, its delegate property won't be nil. So optionally, you can assign it to another reference, and then assign your object, which conforms toUIScrollViewDelegate
, to it. For example:So that you can implement
UIScrollViewDelegate
methods with ease. And yourUIPageViewController
will call your delegate's-scrollViewDidScroll:
method.By the way, you may be obliged to keep original delegate, and respond to delegate methods with that object. You can see an example implementation in
ViewPagerController
class on my UI control project hereI faced the same thing recently. My
UIScrollview
was on paging mode and every page contained aUITableView
and like you described it worked but not as you'd expected it to work. This is how solved it.First I disabled the scrolling of the
UIScrollview
Then I added a
UISwipeGestureRecognizer
to the actualUITableView
for left and right swipes.The action for those swipes were:
This works flawlessly, the only down side is that if the user drags his finger on the
UITableVIew
that will be considered as a swipe. He won't be able to see half of screen A and half of screen B on the same screen.Instead of using
UIScrollView
as a container for these multiple table views, try using aUIPageViewController
.You can even integrate this into your existing view controller setup as a
child view controller
(directly replacing theUIScrollView
).In addition, you'll likely want to implement the required methods from
UIPageViewControllerDataSource
and possibly one or more of the methods fromUIPageViewControllerDelegate
.