2nd Update Thanks to @Segev's comment and reference to another topic, I was able to improve my demo to get it to basically do what I wanted. However, it is still not as smooth as Instagram's implementation, and I was wondering if anyone know how I could improve it to be smoother? Also, I noticed that sometimes (in my demo), when I'm swiping left/right very fast and I want to switch to swiping up/down, it will still continue to swipe left/right until I stop the swiping and let it stop first.
Update: I was able to get the table view to swipe left/right after stopping scrolling up/down by inheriting from UIScrollView and implementing the shouldRecognizeSimultaneouslyWithGestureRecognizer and shouldBeRequiredToFailByGestureRecognizer methods from UIGestureRecognizerDelegate. My idea was to return true in shouldRecognizeSimultaneouslyWithGestureRecognizer if the user is scrolling up/down the tableView, and then in shouldBeRequiredToFailByGestureRecognizer to fail the table view's up/down gesture.
But I am still unable to figure out how to let the user scroll up/down or left/right after stopping the initial up/down scroll (and the user's finger is still on the device).
I created a sample project here https://github.com/paulsfds/TableViewsInScrollView. You can test this by swiping down on the table view once, then lift your finger off and while it's still scrolling, put your finger back on to stop the scrolling. While your finger is still on the table view, try swiping left/right and it should work. But with this implementation if you try to swipe down the table view multiple times, it will sometimes get stuck because it will think that you are trying to swipe left/right. Any ideas?
Original: I have a couple UITableViews that are within a UIScrollView that has paging enabled, and is setup to let me page left and right so that only one UITableView is visible at a time. Here is a diagram (taken from Conflictive scroll on UITableView within UIScrollView)
+--visible area--+ ---+
+---------`UIScrollView`---------+---------------+| --+|
| +-------------+ +-------------+|+-------------+|| -+||
| | 0 | | 1 ||| 2 ||| |||
| |`UITableView`| |`UITableView`|||`UITableView`||| equal height
| | | | ||| ||| |||
| +-------------+ +-------------+|+-------------+|| -+||
+--------------------------------+---------------+| --+|
+----------------+ ---+
What I would like to achieve is if the user scrolls down the table view, and then lifts their finger off (and the scrolling down animation is still happening), the user can chose to swipe left and right to go to the next table view. Right now if the user scrolls down the table view, and then lifts their finger off and while the scrolling down animation is still happening, and then puts their finger back on to swipe left and right, it will not allow the user to scroll left and right, and I am stuck viewing the already visible table view unless I wait for the table view scrolling to stop completely and then swipe left and right.
TL;DR Basically I cannot scroll up/down the table and swipe left/right in the scroll view at the same time, but I would like to be able to do this. An example of this would be in the iOS Instagram app on the Activity tab. You can scroll down and then swipe right while the table view is still scrolling.
Here's an example project that works: https://github.com/rishi420/SwipeWhileScroll
You can read more about this topic here:
Cross Directional UIScrollViews - Can I Modify the Scrolling Behaviour?
Unfortunately Apple does not support embedding UITableViews inside UIScrollViews:
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIWebView_Class/index.html
IMPORTANT
You should not embed UIWebView or UITableView objects in UIScrollView objects. If you do so, unexpected behavior can result because touch events for the two objects can be mixed up and wrongly handled.
However with that said, it still may be possible to achieve what you're looking for. Have you tried setting delayContentTouches
to true so that the scrollview sends its failed scrolled-gesture (i.e. the horizontal scroll) to its children (i.e. your tableview)?
self.yourScrollView.panGestureRecognizer.delaysTouchesBegan = true
While this question has an accepted answer, I wanted to provide my own solution for others who may have similar problems:
Use a UICollectionView to page the UITableViews instead of UIScrollView
Basic steps using UIStoryboards:
As long as your configure your UICollectionView's datasource properly it should page just fine.
I've just done something with a similar functionality.
What worked out for me was to make an extension for the UIPanGestureRecognizer (I'm working with swift 2; if you want I could rewrite the solution for objC) so I can know when the user got the finger out of the device. Then you can able to swipe left/right I suppose.
Here is the code, I explain it below:
extension UIPanGestureRecognizer {
public override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent) {
state = .Ended
NSNotificationCenter.defaultCenter().postNotification(NSNotification(name: "panningEnded", object: nil))
}
}
This is the only way I could reach the touchesEnded for that specific gesture. All you have to do from here is add an observer for the notification you posted and then make able for the user to swipe. Let me know if this was useful.
Kind Regards
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With