iOS UITableView is not scrolling after adding cells - iphone

I have a UITableView that represents playable rounds in a game. On first launch, only two cells are shown in the tableView. As the user beats levels, more and more rows are added to the tableView. I reloadData every time the tableView is displayed (which happens each time the user beats a level).
Once the tableView contains enough cells to require scrolling, the tableView will not scroll and where the user left it. It will scroll to reveal that the cells are down below, but when the user releases their finger, the tableView bounces back, not allowing the user to interact with those cells that require scrolling to see. After completing another level and returning back to the tableView, the view will scroll properly.
When the scrolling issue exists, it is as though the tableView does not realize that it is big enough to require scrolling, so it bounces back to its original position, despite the fact that there are cells that are displayed down below when the user attempts to scroll.
I do not implement the heightForRowAtIndexPath or heightForHeaderInSection methods in the tableView's delegate, so that should not be interfering. I have searched this site and Google for similar issues, and have tried a few things including setting the contentSize, but have been unsuccessful.
Is there any reason for this lack of scrolling? Or, more importantly, is there a way to fix it? Thanks!
EDIT:
I see some comments asking about the frame. I logged the frame of the view the table is in, the frame of the tableView itself, and the tableView's content size in the viewDidAppear method of the view the table i in.
Here are the results when the view appears the time before scrolling is necessary. Scrolling behavior is as expected; the user can scroll past the visible area, and it bounces back.
view.frame: {{0, 20}, {320, 460}}
tableView.frame: {{0, 145}, {320, 315}}
tableView.contentSize: {320, 308}
Here are the results when the view appears when scrolling should be necessary. Scrolling will allow the cells below to appear, but when the user releases their finger, it bounces back when it should not.
view.frame: {{0, 20}, {320, 460}}
tableView.frame: {{0, 145}, {320, 315}}
tableView.contentSize: {320, 352}
Note that the contentSize.height did change by 44, as it should have after a new cell was added. The contentSize.height is now larger than tableView.frame.height, but the scrolling behavior does not reflect this.

The protocol UITableViewDelegate conforms to UIScrollViewDelegate, so all you need to do is to implement the methods -scrollViewWillBeginDragging and -scrollViewDidScroll directly in your UITableViewDelegate implementation and they will be called automatically if the implementation class is set as delegate to your UITableView.
So in those methods you can implement logic related to showing content of your tableView. Like suppose you said while scrolling it should show new cell i.e the top most cell must hide at that time. You could write logic in above method as,
//set your content of tableview to show new cell each time.
OR for scroll direction , you have method - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView,
// you can set here start and end coordinates and change them accordingly when scroll decelerates.
Writing your code in such way will not make the scroll bounce back. And you will get perfect results.
Hope this helps.

self.tableview.scrollEnable=YES;//Paste this line where initialized UITableView.

Related

Swift tableView setContentOffset doesn't bounce

I'm having a problem understanding mechanism of setContentOffset, if my tableView has contentSize.height of 100 points and I set content offset to 200 points the table won't bounce to content like it would do if user manually scrolled tableView to 200 points. User has to tap tableView in order to bounce back to content.
Is there a way to mimic user scroll with setContentOffset?
Swift 4
You can try
tableView.scrollToRow(at: yourIndex, at: bottom/middle/none/top, animated: true/false)
Place this in ViewDidLoad in your TableViewController and the tableView will begin at your desired place. If you set animated to true then you will have your desired scroll effect.
As far as setContentOffset that is more to simply offset the tableView so that it is positioned more correctly, not meant to mimic a scrolling action

Recreate UIPickerView with just one row showing

I need a "PickerView", that behaves like a normal UIPickerView, but only shows one row of data and has a custom design.
Something like you see in the image, showing the transition from subview 1 to subview 2. After the user lifts his finger and after the scrolling stops, only one subview will be shown:
IMAGE
So basically a scrollview which:
is endless in both, positive and negative directions by showing the same entries over and over
uses paging across several subviews
only shows one subview when not scrolling, and no more than two subviews when scrolling.
I can get a endless scrollview to work, but not with paging enabled. Paging will always limit my scrolling to the next subview.
So I'm thinking about creating my own UIView subclass which custom scrolling behaviour to mimic a UIPickerView. But before doing so, I wanted to get some opinions about the idea in general. Is creating a custom UIView the right way to go? Anyone has some experience with the expected performace? (There will be timers to handle the scrolling algorithm, which has to be recreated of course... :)
Another approach would be to subclass UIScrolView and implement the paging myself. I know when the scrollView starts decelerating
, so maybe there is a way to overwrite the contentOffset to have it scroll into the right position...?!
Any help is appreciated! Thanks!
Here is a great custom component, which seems to be able to do everything you need:
http://dev.doukasd.com/2011/04/infinite-scrolling-dial-control-for-ios/
It's not endless, but rather a modified UITableView with a huge number of cells.
Would it be feasible to just use a UIPickerView, but clipped to the middle row? You could turn off showsSelectionIndicator to remove the overlay and have the delegate pass back custom row views.

Manually scrolling UITableViewController when a UITextField becomes first responder

Harrr pirates!
I'm trying to make a data entry screen using a UITableViewController. It contains a grouped table view with two sections, each with a few (2 and 4) rows with a UITextField inside them.
When any of the UITextFields become first responder they scroll into view automatically. Great, you would say, but I want to scroll the whole section into view, not just the row containing the UITextField that became first responder.
I don't allow the user to scroll the UITableView by hand and I know to what position it should scroll to display correctly. However, I can't get my UITableViewController to stop automatically scrolling the UITextField into view for me.
Searching StackOverflow I can find a lot of questions about how to resize the UITableView when the keyboard appears, but this doesn't stop the automatic scrolling.
Any suggestions? Your help would be much appreciated!
TableView is basically an extension of scrollView therefore if you want to do the scroll yourself you should use the scrollview API.
Set the contectSize property to the size of the screen without the keyboard and the contentOffset to the location on the table you want to scroll to

Unwanted automatic scrolling with UIScrollView and UITextFields as subviews

The "too long; didn't read" version: Is there any way to disable the automatic scrolling behaviour of UIScrollView when telling a UITextField to becomeFirstResponder?
I have a scroll view with paging enabled and several views as subviews, each subview being controlled by its own view controller. Each subview has a UITextField.
The requirement is that when a page is scrolled into view, it's text field should become first responder.
This is fine when using finger swipes to scroll -- I use the scroll view delegate method scrollViewDidEndDecelerating: to know when scrolling stops and a page is in view, I can tell the text field to become first responder.
However, when the scroll view is "autoscrolled", as in when telling the scrollview to scrollRectToVisible:animated:, the scroll view delegate method for deceleration isn't called. I use this method when scrolling newly created pages into view without the user's interation, or when the user taps the UIPageControl.
My solution was to simply set the first responder status of the text field before telling it to scroll into view - but it seems that telling a text field that is in a scroll view to become first responder causes the scroll view to automatically scroll it into view.
I assume this is behaviour used when putting text fields in table view cells (since table views are scroll view subclasses). If you set up a small test app, with a table view, and a text field within a table cell, if the keyboard would obscure the table view cell when it becomes first responder, the table view will automatically scroll it to be visible.
I don't understand, though, why this behaviour occurs in my example, where I'm not using a table view - just a plain scroll view.
I should also mention that my scroll view has vertical scrolling disabled and only scrolls horizontally.
I have tested in another test app that puts text fields as direct subviews of a scrollview (no view controllers or container views) and the same happens. If you tell a text field that is offscreen to become first responder, the scroll view with automatically scroll it for you.
This wouldn't normally be a problem, but it seems to screw up the paging of the scroll view. When I scroll with my finger, each view bounces and is centred properly. But when I scroll a rect to be visible with animation and tell a text field to become first responder, scroll view seems to become conflicted with itself and the view is only scrolled part of the way into view, and isn't centred.
Then, if I touch a view using my finger (not swipe, or even move), the scroll view jumps back to the first page.
My current work around for all this silly auto scrolling behaviour is to use an NSTimer to determine when to update the first responder.
I do the manual scrolling in code using scrollRectToVisible:animated and then after 0.3 seconds, call my method to update the text field to be first responder. (0.3 seconds was trial and error, trying to see which seemed to be the smallest amount of time to allow for the animation but still be long enough not to cause the conflict with the scrollview.
As you can see, this isn't elegant, and is likely to break.
Is there any way to disable the automatic scrolling behaviour of UIScrollView when telling a UITextField to becomeFirstResponder?
Call becomeFirstResponder, then right away, set the contentOffset of the scrollview to its current position..
[textField becomeFirstResponder];
[scrollview setContentOffset:scrollview.contentOffset animated:NO];
Not an answer to your question, but it should fix the problem:
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
// Make the text field first responder...
}

How to display scrollbar in UITableView

I want to display some kind of indication to guide user to scroll.
Usually when we touch the UITableView scrollbar appears if needed. But I want this scrollbar indication already displayed on my tableview.
How is it possible to do so?
If you have a table view that goes offscreen, you can call
[self.tableView flashScrollIndicators];
and they will flash to show the user that they are there. This is usually put in viewDidAppear.
(If you inherit from UITableViewController then you will have a self.tableView instance variable, if not then substitute another UITableView.)
If you a scroll view's entire contents fit within its view then no scroll bars are displayed; to test this display a table view with only one cell. If the content size is larger than the view's frame then scroll bars will be displayed; only then will [self.tableView flashScrollIndicators]; actually flash scroll indicators.
There's no way to force the scrollbar to appear, short of messing with the internals of UITableView(which you shouldn't do), or redesigning your own table view class.
Per the documentation of UIScrollView's showsVerticalScrollIndicator property: "The indicator is visible while tracking is underway and fades out after tracking."