How to auto-scroll UITableView? - iphone

I am trying to do something interesting.
I am pulling some JSON data and populating cells in a UITableView. How can I make the UITableView scroll ever second or so? I want to give the effect that as new data is coming in, the table is scrolling, so it is streaming.
Any ideas?

Yes, use scrollToRowAtIndexPath:atScrollPosition:animated:.
You could also use UIScrollView's scrollRectToVisible:animated: if you want to have more finegrained control and can calculate exactly what your scroll position should be in pixels. (UITableView is subclass of UIScrollView.)
But if you are just adding cells, sounds like you could also just use insertRowsAtIndexPaths:withRowAnimation:, this is also "interesting."

Just do this
[table reloadData];
NSIndexPath *myIP = [NSIndexPath indexPathForRow:[arrayIn count]-1 inSection:0] ;
[table scrollToRowAtIndexPath:myIP atScrollPosition:NULL animated:YES];
in anywhere where arrayIn is your array by which your table populate.

you can use uitableviews scrollToRowAtIndexPath to do this....heres a link reference
You can call this method whenever as youd like to scroll your tableview

And you can call performSelector:withObject:afterDelay: for the timer effect - although if you are really pulling in data every second, it's best to just reloadData as you go.

Related

Getting NSIndexPath of a row for UISwitch

I have a tableview with custom UITableViewCells, each row in the table has a UILabel, UISwitch and detail disclosure indicator.
I'm looking for the best method of capturing the UIControlEventChanged for the switch but I also need the NSIndexPath of the switch that changed to update Core Data.
I don't want the UISwitch as an accessory type either.
I've been googling this for hours and the solution that keeps popping up is to use
[switch addTarget:self action:#selector(switchTapped:) forControlEvents:UIControlEventChanged];
then in the switchTapped: method use the following to get the NSIndexPath
NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)[[sender superview] superview]];
Is there a better way of doing this? I already have UITableViewCell subclassed, can I put a method in this class to return the NSIndexPath for a given switch?
Thanks in advance for any help
I'll take another opportunity to link to my answer here - tags and view hierarchy walking are clunky, error prone and unnecessary, and I see them recommended all over the place in SO answers. You can find the index path of any control using its frame and the table view's indexPathForRowAtPoint: method.
Setting a proper tag for the switch in each row of the table is a feasible solution. Set the tag according to the indexpath of the row in which it is present.
That way you avoid the possible problems that might arise to changes in view hierarchy.
This post might also help you.

iphone - scrollRectToVisible issue

This functions perfectly, but I want to make it an once-function, not fixed-function. When I change tableview with other data, the data displays at the index from previous tableview. So my solution to this is implementing the code below. When I implement this, it works, but when I scroll down, it scrolls up all the time, so it is virtually impossible to scroll down further. Any idea how to make it performs only once when I change tableview?
The code:
[tableView scrollRectToVisible:CGRectMake(0,0,1,1) animated:NO];
Edit 21 august:
Guys, thank you very much! The code was in cellforrowatindexpath. I moved it to inside the function which changes tableview and it works like a charm :D
You could override the reloadData method if that is how you are reloading the Table View with new data and put the code in there. Something like this in your table view controller should suffice:
- (void)reloadData {
[super reloadData];
[tableView scrollRectToVisible:CGRectMake(0,0,1,1) animated:NO];
}
If it's scrolling up every time you scroll down, I assume you put the code in the cellForRowAtIndexPath method which will get called every time you want to present the cell. This is not the correct place to put that code.
It IS a once-function. Most probably, this code of yours is executing again & again. If you have kept this in a function such as cellForRowAtIndexPath:, which is called frequently, that may be the cause of this problem. Where have you put it?
HTH,
Akshay

Programmatically move/animate a UITableView row from one position to another

I have a UITableView and I want to programmatically move one row from position N1 to position N2 and I would like it to animate from the old location to the new. I've looked through the UITableView documentation and I'm only seeing inserts, reloads, and deletes. Do you know of a way I can do this programmatically?
A couple of notes:
I know that I can animate the deletion from location N1 and animate the insertion to location N2 at the same time. That's my fallback, but I'd like the user to understand that it is truly moving from N1 to N2.
I'm not talking about allowing the user to drag it from one place to another. I understand how to do that, I'm looking for a way to initiate and animate the move programmatically.
I've dealt with something kind of like this in the past and the solution is not pretty but it does work.
Basically you have to do some math to calculate where on the screen the row is. Then adjust that based on the y property of the contentOffset of your UITableView.
You can do that like this:
[myView convertPoint:localPosition toView:nil];
Then you would construct a new UIView that's identical to your view. Set its frame to be directly on top of the UITableViewCell you're trying to move. Add it as a subview of your app's main UIWindow.
You'll want to set userInteractionEnabled or scrollEnabled to NO on your UITableView while all of this is going on so that the user can't muck with the position of things throughout the process (just remember to set it back to YES when everything is done animating).
Then animate it to the new position however makes the most sense.
I understand you may have to scroll the UITableView in the process of all of this, which complicates things considerably, but you can animate that scrolling as well.
You'll of course have to do similar operations on the row you're animating to if it is necessary in your app.
Like I said its not easy or pretty. But I do understand what you're trying to accomplish and I think the effect is super awesome when it's pulled off properly.
If anyone has a better idea of how to pull this off without going insane I'd love to know, but this type of implementation is the best I've been able to do.
[table beginUpdates];
[table moveRowAtIndexPath:indexPath toIndexPath:destIndexPath];
[table endUpdates];
If you're using iOS 5 or hight you could use the method:
- (void)moveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath
For example:
//move last cell one row up.
NSIndexPath *oldPath = [NSIndexPath indexPathForRow:[items count] - 1 inSection:0];
NSIndexPath *newPath = [NSIndexPath indexPathForRow:[items count] - 2 inSection:0];
[[self tableView] moveRowAtIndexPath:oldPath toIndexPath:newPath];
Check out apple's documentation here.
I guess your best fallback would indeed be the deletion and insertion method, something like:
[tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:oldPath] withRowAnimation:UITableViewRowAnimationLeft];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newNewPath] withRowAnimation:UITableViewRowAnimationLeft];
[tableView endUpdates];

TableView's viewWillAppear() called but data is not refreshed

Sometimes tiny looking problem is ignored to handle in the last but you never know that will become nightmare for you, happening with me.
Thanks in advance, problem my app's settings page contains tableView and every setting element is one of the view. One of the setting item (row) offers show expands a few list of items in another listTableView. After making a selection in listTableView when i come back to my settings tableView using navigationItem.leftButton (Back), selected item value overlaps the previous item's value, in the sense [tableView reloadData] in viewWillAppear works fine but tableView rows are not fresh drawn. It doesn't refresh the cell's UI.
Note that if settingTableView has any subview like UIButton etc it has the latest value, i can use that as workaround but the only problem is when is select this row again Selection has old value that overlaps new value on selecting the row.
I will appreciate any suggestion or sample code using will be great help.
Thanks a ton
Amit Singh
Use [tableView reloadData]; in your viewWillAppear method.
or use [tableView reloadData]; in viewDidAppear method
The problem you are facing is perhaps due to portion of cell that is reusable and the one that is not reused. Check out the code you are writing inside the block of
if(cell==nil){}
components you have created inside block will not get recreated and others might be recreating causing the overlapping on the cell.
In my case, I had to use [self.tableView reloadData]; rather than [tableView reloadData]; in the viewWillAppear method.

VERY weird UITableViewController.tableview behaviour on scrollToRowAtIndexPath

hey all, I'm very confused here, i've been trying to figure this one out. I have a UIViewController, viewControllerBrowse, with two TableViewController, Designations & Types, I call a second UIViewController, viewControllerSelectLibrary, that makes some SOLite operations and fills two arrays from where the first two TableView feed.
When I'm going to call back viewControllerBrowse, I perform inside a NSThread:
[appDelegate.viewControllerBrowse.tvcTypes.tableView reloadData];
[appDelegate.viewControllerBrowse.tvcTypes.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:YES scrollPosition:UITableViewScrollPositionTop];
[appDelegate.viewControllerBrowse.tvcDesignations.tableView reloadData];
[appDelegate.viewControllerBrowse.tvcDesignations.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:YES scrollPosition:UITableViewScrollPositionTop];
What TRUUUULY puzzles me is that on tvcTypes case, its tableView gets its first row selected and scrolled to the top
BUT, for tvcDesignations, its tableView get ITS FIRST ROW SELECTED BUT IT DOES NOT SCROLL TO THE TOP
the fact that the first row is selected tells me that it's not a problem of reference in the appDelegate, it's as if only half the method is working/??????????????
anyone hit this one before??????
Just a guess, but what happens if you pass NO to animated? I've never seen this behavior specifically, unfortunately, but I have seen some animations cause weird interactions.
Also, which view controller is visible? Either of them?