I have 3 tableview which have 10 rows, after pull to scroll it adds next 10 rows, but the scroll goes to top, I want it from the same row, which was before.
- (void)insertRowAtBottom {
int64_t delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self moreClicked];
});
}
You can save the last index path of the table view in any variable when pull happens and then use the below code to scroll the table
NSIndexPath *lastIndexPath = [NSIndexPath indexPathForRow:(numberOfRows - 1) inSection:(numberOfSections - 1)];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:lastIndexPath inSection:0];
[self.tableview scrollToRowAtIndexPath:indexPath
atScrollPosition:UITableViewScrollPositionTop
animated:YES];
For Scroll positions you can have any value within the list.
UITableViewScrollPositionNone,
UITableViewScrollPositionTop,
UITableViewScrollPositionMiddle,
UITableViewScrollPositionBottom
There are a few ways to implement "paging" in tableView.
One approach is: Assuming your tableView is populated from an objects array -
When you scroll down and fetch the next 10 items - just append the newly added data to your datasource array, and then call [self.tableview reloadData];
this will keep you exactly where you were. no need for scrolling methods or animations.
Related
I'm building an easy app for chatting, each time I type in a sentence, the sentences is added into an array(which used to load the table view in cellForRowAtIndexPath delegate method), then I reload the table view. At last I use the following code to scroll the table view to the bottom
if ([self.chatList numberOfRowsInSection:0] != 0) {
NSUInteger rowCount = [self.chatArray count];
NSIndexPath* indexPath = [NSIndexPath indexPathForRow:rowCount-1 inSection:0];
[self.chatList scrollToRowAtIndexPath:indexPath
atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
however, the table view sometimes performs well, sometimes only scrolls to the second to the last line……
Try changing the scrollPosition to UITableViewScrollPositionBottom.
I'm writing an iPhone app with a UITableView as the primary user interface. Each section consists of two rows, a header and the body. When the user clicks on the header, I remove the second row by changing the numberOfRowsInSection value:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
cbwComponent *comp = [_componentController objectInListAtIndex:section];
if([comp hasContentsView] && !comp.contentsHidden){
return 2;
}else
return 1;
}
When the user selects the header, I'm using the following code:
comp.contentsHidden = YES;
[self.tableView beginUpdates];
NSArray *deleteIndexPaths = [[NSArray alloc] initWithObjects:[NSIndexPath indexPathForRow:1 inSection:indexPath.section], nil];
[self.tableView deleteRowsAtIndexPaths:deleteIndexPaths withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];
It's working great, with a nice smooth fade effect. The problem is, I'm trying to add an indicator in the header cell (row 0) that changes when it's clicked on. To change that image I have to refresh the top row as well as the second row, which makes the transition look bad (well, not nearly as smooth). Is there a way to change the image in a UITableViewCell without refreshing the cell?
Thanks
EDIT: I figured it out! You can maintain the smooth transition as long as you reload that first row before you make the change to the second row. It has to be called inside of [tableView beginUpdates];
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:[[NSArray alloc] initWithObjects:[NSIndexPath indexPathForRow:0 inSection:indexPath.section], nil] withRowAnimation:UITableViewRowAnimationNone];
...
[self.tableView endUpdates];
Did the trick.
You could also subclass a tableview cell and implement a view transition in it that can be called from your view controller. You could then call that without having to reload the cell.
[(YourCustomCell*)[tableView cellForRowAtIndexPath:indexPathOfYourCell] fadeInIndicator];
I have a table view with a number of cells. When I add a new cell (using a modal view controller) I'd like to show the user the newly added cell. To do this I want to scroll the table view to the new cell, select it and immediately deselect it.
Right now, I'm sending a deselectRowAtIndexPath to my table view after a timed interval:
- (IBAction)selectRow
{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:7 inSection:0];
[self.tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionTop];
[self performSelector:#selector(deselectRow:) withObject:indexPath afterDelay:1.0f];
}
- (void)deselectRow:(NSIndexPath *)indexPath
{
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
}
I'm wondering if there's a nicer way to do this. It works well, but I don't like relying on a static timer to perform an operation which could sometimes take a different amount of time (e.g. if the table was very long).
Edit: Note that selectRowAtIndexPath:animated:scrollPosition won't cause the UITableView delegate methods to get fired. Neither tableView:didSelectRowAtIndexPath: nor scrollViewDidEndDecelerating: will be called. From the docs:
Calling this method does not cause the delegate to receive a tableView:willSelectRowAtIndexPath: or tableView:didSelectRowAtIndexPath: message, nor will it send UITableViewSelectionDidChangeNotification notifications to observers.
UITableViewDelegate is an extension of UIScrollViewDelegate. You could implement one of the UIScrollViewDelegate methods and use that to determine when to deselect the row. scrollViewDidEndDecelerating: seems like a good place to start.
Also, I personally find the performSelector... methods limiting due to the 1 parameter restrictions. I prefer to use GCD. The code would look like this:
- (IBAction)selectRow
{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:7 inSection:0];
[self.tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionTop];
//deselect the row after a delay
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
});
}
I know that we can scroll to the bottom of the UITableView in a regular UITableViewController by using:
- (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated
Where indexPath can be found by doing a count of how many objects are there in the array of objects. However, in three20.. how do we do the same thing as we don't have the array of objects in the table?
I don't know if there's something that makes three20 different, but this should work in any UITableViewController subclass:
- (void)scrollToBottom {
NSInteger section = [self.tableView numberOfSections] - 1;
NSInteger row = [self.tableView numberOfRowsInSection:section] - 1;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section];
[self.tableView scrollToRowAtIndexPath:indexPath
atScrollPosition:UITableViewScrollPositionMiddle
animated:YES];
}
Im trying to highlight the first row in my table upon first loading the data and just cannot get it to work!
I have tried lots of ways with no joy, the latest attempt being this:
NSUInteger indexArr[] = {0,1};
NSIndexPath *n = [NSIndexPath indexPathWithIndexes:indexArr length:2];
[self.tableView scrollToRowAtIndexPath:n atScrollPosition:UITableViewScrollPositionTop animated:NO];
try
[self.tableView selectRowAtIndexPath:n animated:YES scrollPosition:UITableViewScrollPositionTop];
you should probably do this after your view has appeared.