How can I make UITableView less sensitive to vertical scrolling? - ios

I have table view that has more than 10 rows and inside each row I'm placing a hortizontally-scrolling scrollview (you can thumb through images much like in Coverflow).
The problem is that UITableView is too sensitive to vertical scrolling. When I'm trying to scroll left and right in a particular scrollview (inside of any cell), the table view starts scrolling up or down once it detects even the slightest movement of my finger upon the y-axis.
Is there a way I can change this and set a higher vertical-scroll threshold for the table view?

Here's a couple suggestions. Try them and see how they feel.
Suggestion 1
When you dequeue your tableViewCells, try calling this:
[tableView.panGestureRecognizer requireGestureRecognizerToFail:cell.scrollView.panGestureRecognizer];
Suggestion 2
Try setting this on your tableView:
self.tableView.delaysContentTouches = NO;
That property defaults to YES. It delays touches to the content of the table view cells by a fraction of a second, to help it recognize the difference between a tap and a drag.

Related

How to create up/down swipeable UITableView?

I have a UITableView in the bottom of UIViewController and tableview height is 100 point now.
The tableview has 20 cells and tableview's header view is 100 point. And I've added a up UISwipeGestureRecognizer and a down UISwipeGestureRecognizer in table view header.
Now I want to change the tableview height constraint constant to 400 in up gesture action and change the tableview height constraint constant to 100 in down gesture action.
Now the problem is gesture recognizer isnt working in tableview
header when tableview scroll is enabled.
If tableview scroll is disabled then the gesture recognizer is
working. But unable to view all cells once the tableview height is
changed.
Here's a different approach. Don't use swipe gesture recognizers at all.
Instead, make the table always the full 400 points tall. Set its contentInset.top to 300. This will allow the table view to scroll so that only its top 100 points of content are visible at the bottom of the screen. Specifically, the table view will allow its contentOffset.y (which is its vertical scrolling position) to go down to -300 (instead of only down to 0). The table's content always starts at y = 0, so when the table's contentOffset.y is -300, only the top 100 points of its content are visible. As the contentOffset.y increases, more of its content becomes visible.
Then, override the table view's point(inside:withEvent:) method to return true only for points with y >= 0. This means the table will ignore (pass through) touches above its content when its content is scrolled so only the top 100 points are visible.
This is the final effect for a small table:
or for a big table:
You can find a detailed explanation (in Objective-C) and a link to the full test project (also in Objective-C) in this answer.
As it may help others, here is the simplest possible solution to this type of problem.
Extremely simple solution -
no tricks, nothing fancy -
don't have a "table view header".
Just make a new UIViewController
class TableWithRedTop: UIViewController
that has ...
[ red area .. swipe detection ]
[ main area - the table view]
Then simply put 'TableWithRedTop' inside a container view.
(Container view tutorial if you need one.)
In your MainView just have a call
func toggleTableHeight
When 'TableWithRedTop' gets a swipe, have one line of code to call toggleTableHeight in MainView
Note that in toggleTableHeight you can easily animate the height change, tilt it on an angle, duplicate it or do anything you want, as you're using a container view in MainView.
I'm going to make another suggestion that may solve the issue for you.
It could be what you want is an:
"self-expanding" table...
First implement the following with no animations, for simplicity.
You have two heights for the table, small and large.
Start the table on height small.
Remarkably, you only have to implement these two rules: just two simple lines of code:
Any time the user is scrolling upwards - in fact, change to "height large".
Any time the user is scrolling downwards, and, you are at the top position of the table (i.e. you can see cell #1) in fact change to "height small".
It's one of those things that is "so simple, it's hard to believe it works!"
It's sometimes referred to as a "pull-up table" I think.
(Note. If you're not familiar with detecting when the user is scrolling, fortunately it is trivial - code shown here for example.)
Set both swipe gesture’s cancelsTouchesInView to true and make sure that the gestures are added directly to the header and not the tableView.
That should do the trick, but so should adding a view with the gesture recognizes to the container view and setting it’s constraints to match the tableView’s top, left, and right constraints and setting its height to 100.

how to create a table with a fixed first column and row?

I'm trying to create a table with a fixed first column and row. I tried to implement it like the scheme below (it's a vertical UIScrollView with a horizontal UIScrollView inside). The problem is that I need to make them move together if I drag my finger across the screen diagonally with the acceleration and bouncing animations. I already tried creating a view on top, getting the movement with touchesBegan: and touchesMoved: and changing the contentOffset programatically but it has laggy and without acceleration and bounce. Any ideas? Thanks in advance
scheme:
From the first look:
Parent View: ScrollView with vertical Scroll only.
Inside:
First Row: UICollectionView (with horizontal scroll)
First Column: Normal UIView (or table view or colleciton view - depends on your setup)
The rest of cells: UICollectionView with horizontal scroll
Add an array value at the index path 0 manually. So that you will get a cell value constantly.

Adding subview to UICollectionView - disables scrolling

I want to add a subview to a UICollectionView in order to make a left panel that scrolls with the collectionview.
Using
[self.collectionView addSubview:myView]
all touches become disabled and I can no longer scroll the view. I've read that adding a subview to a collectionView like this is bad practice.. is this true? Why does it disable touches from reaching the collectionView event when
userInteractionEnabled = NO
I'm trying to do this: imgur link by grabbing the frame position of the first cell in each section, and adding a dot with to myView with the same y value.
Thanks for any help!
Adding subviews using the addSubview: method to a UICollectionView is very bad practice. It can cause a lot of different problems in the normal behaviour of the CollectionView. It can obstruct the views underneath it, capture the touch events, preventing them from reaching the actual scrollView inside the CollectionView, etc. The subviews added using this method will also not scroll as the other elements in the CollectionView do.
The correct way to do what you want is to implement a new type of UICollectionViewCell for the dots, and compute their locations in the prepareForLayout and layoutAttributesForElementsInRect: methods. Basically you'll have either one or two cells in each row. Which ones will have two rows will be determined by you in the methods I've mentioned.
In fact, Apple's docs have a perfect example that's even more complex than what you're trying you achieve. You should check it out from this link.
May I know the purpose of that scroll view ? Because, if you're looking for a subview that displays only a label or image etc., You can use custom collectionview cell instead if I am not wrong... Hope it helps :) :)

UITableView Not Scrolling

I have a tableview which will not budge when touched. It is very confusing to me. It is the most recently added subview (I checked - it is the last entry in my view's subviews array) and for some reason it just won't scroll up or down. If I tap multiple fingers wildly on the tableview it will one in a while highlight the cell under one of my fingers, but it will not scroll even a little. I have set the number of rows to 100 (many more than are visible on screen) and I have set the 'bounces', 'scrollEnabled', and 'userInteractionEnabled' properties to YES.
I know that I have not provided much to go on here, but if anyone could at least give some tips on how to go about debugging this I would be very grateful. Can I log from within the tableView gestureRecognizer handling method? Can I test where my touches are going?
Please help!
Thanks.
A TableView is basically a specialized ScrollView. If it's not scrolling, it seems to me it could be one of two things. Either something is on top of the TableView and is capturing the gesture events before the TableView can get them, or You have set the bounds and contentSize incorrectly. For a TableView or ScrollView, the bounds of the view should be the visible area, and the contentSize (should be handled by the TableView without you needing to do anything) is the size of all the cells in the Table.
So I would check the bounds of the table view and make sure you are setting that to the contentSize, since that would cause it nor to scroll.
Just to make sure it's on the top, try calling
[view bringSubviewToFront:tableView];
In my case tableview "User Interaction" was disabled. I just enabled it & works.
In my case, tableView "canCancelContentTouches" was not enabled. I set it to true in the storyboard.
Can you check the frame of the parent on which the tableview is added? Make sure the parent view have correct frame to include the table view. I have faced this issue sometime back my table view was not responding to touches and there was some problem with frame size. Also do check the bounds and frames of your tableview
-anoop
Please check tableview scroll is enabled.
I just hate XIB and Storyboard. After 30 mins of debugging it come to know that scroll was not enable in XIB.
Thanks
Basically, Table view is just a kind of scrollview. So in case it is not scrolling You should be sure that if the frame size of your table view is less than the contentSize of your table view. For this just log the frame and content size of tableView's scroll view. If you found that frame size is greater or equal to your content size, just correct your layout constrain of your view. And I hope it will work.

UITableViewCell Reuse issues with horizontal tableview

I have a slightly complicated system that I am having some reuse issues with, wanted to get some feedback. Basically it is a vertical tableview, and each cell contains another tableview that is rotated 90 degrees, so that each cell scrolls horizontally. Each horizontal cell is also set up to scroll infinitely with paginated responses from an API. I am having issues where cells are copying on top of each other when the vertical table is scrolled down. I have reuse identifiers set up correctly and in each of the horizontal tableviews I am running the following:
- (void)prepareForReuse
{
[_horizontalTableView reloadData];
}
If I turn off reusing cells the issue doesn't happen, but the vertical scrolling performance suffers. I am wondering if its possible that reusing cells in this type of a set up just isnt possible? Any experience with this is helpful. Thanks.
This is not a direct way to solve your issue, but I believe if you use a horizontal scroll view inside each vertical cell, you will have this done faster and with less weird behaviours. I also believe this is not a standard way, so weird stuff will happen.
All you do is set or extend the content size of the scroll off screen continuously to create an infinite scrolling behaviour. Create views within the scroll view pragmatically to simulate each cell. Hope this helps.

Resources