So I've got a universal app, and I'm trying to hide a border of a cell, if the next cell in the tableView has an error state. I use this code in tableView:cellForRowAtIndexPath: to determine if the cell should hide it's bottom border or not:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
DCSMCDynamicBaseCell * cell = [self.cellManager dynamicCellForComponent:[self componentForIndexPath:indexPath] atIndexPath:indexPath canShowErrors:self.shouldDisplayErrors];
NSIndexPath *nextIndexPath = [self.tableView nextRowForIndexPath:indexPath];
if (nextIndexPath) {
DCSMCDynamicBaseCell *nextCell = [self.tableView cellForRowAtIndexPath:nextIndexPath];
DCSMCDynamicBaseCell *currentCell = [self.tableView cellForRowAtIndexPath:indexPath];
if (nextCell.invalidState) {
cell.shouldHideBottomBorder = YES;
NSLog(#"%#", currentCell);
}
}
if ([cell isKindOfClass:[DCSMCDynamicCopyCell class]]) {
[((DCSMCDynamicCopyCell *)cell).webView setNavigationController:self.navigationController];
}
[cell setDelegate:self];
self.previousIndexPath = indexPath;
return cell;
}
My nextRowForIndexPath looks like this:
- (NSIndexPath *)nextRowForIndexPath:(NSIndexPath *)indexPath {
NSInteger currentRow = indexPath.row;
NSInteger currentSection = indexPath.section;
NSInteger numberOfRows = [self numberOfRowsInSection:indexPath.section];
NSInteger numberOfSections = [self numberOfSections];
NSIndexPath *newIndexPath;
if (currentRow + 1 < numberOfRows) {
newIndexPath = [NSIndexPath indexPathForRow:currentRow + 1 inSection:currentSection];
} else if (currentSection + 1 > numberOfSections) {
newIndexPath = [NSIndexPath indexPathForRow:0 inSection:currentSection + 1];
} else {
newIndexPath = nil;
}
return newIndexPath;
}
On my iPhone 6 simulator, everything works fine. It gets the cell and hides the bottom border of it. I may refactor this a bit in order to make sure it works in all scenarios, but for a first pass before testing, it works great.
The issue is on the iPad, every single cell returns nil when using the cellForRowAtIndexPath: method. Even weirder, on iPad, the screen is big enough so that all cells are visible at all times, so when I call reload data, the cells are already visible and should get returned by this method.
Does anyone know why a cell wouldn't get returned by cellForRowAtIndexPath:on iPad but would on iPhone?
Related
I have a table with one custom cell with one label and one textfield.Am re-using the same cell with some 5 rows. I want to display one view beneath my textfield only if user enters on the textfield. When am entering data in first textfield view should be hidden for other rows and respectively for all other rows. Default height must be 120 and when am displaying my view row height should increased to 250. Here is my code,
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 120;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"DetailsTableCell";
cell = (NewsDetailsTableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[NewsDetailsTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
if (indexPath.row == 0) {
cell.newView.tag = 200;
}
else if (indexPath.row == 1) {
cell.newView.tag = 201;
}
else {
cell.newView.tag = 202;
}
return cell;
}
Here new view is my UIView which am displaying on text change.
- (IBAction)textFieldChanged:(UITextField *)textField replacementString:(NSString *)string {
NSIndexPath *indexPath = [newsTable indexPathForCell:(NewsDetailsTableViewCell*)[[textField superview] superview]];
NSIndexPath *myPath = [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section];
NewsDetailsTableViewCell *newsTableCell = (NewsDetailsTableViewCell*)[newsTable cellForRowAtIndexPath:myPath];
if (indexPath.row == 0 && newsTableCell.newView.tag == 100) {
newsTable.rowHeight = 250;
newsTableCell.newView.hidden = false;
} else if (indexPath.row == 1 && newsTableCell.newView.tag.tag == 101) {
newsTable.rowHeight = 250;
newsTableCell.newView.hidden = false;
} else {
newsTable.rowHeight = 250;
newsTableCell.newView.hidden = false;
}
}
Am getting my view in my text change but row height is not getting changed. Also It still showing 120 height.
Also I tried this,
NSArray* rowsTobeReloaded = [NSArray arrayWithObjects:indexPath, nil];
[newsTable reloadRowsAtIndexPaths:rowsTobeReloaded withRowAnimation:UITableViewRowAnimationNone];
But it didn't work. Should I re-load my tableview again in text change? or am I missing something?
You have to modify the logic in the below method:
The selectedRowNum can be modified as per the row in which the textField is to be shown.
Also, cellForRowAtIndexPath is not used for setting the height of rows in a tableview. Everytime, we call the reloadData or reloadIndexes the heightForRowAtIndexPath method is called.
YOu need to change height in
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (usingNewView){
return 250;
}
return 120;
}
And set logic for usingNewView in
- (IBAction)textFieldChanged:(UITextField *)textField replacementString:(NSString *)string
I have a custom UITableView with UITextFields inside. In cellForRow... I made the textFields delegate to self. (In my main VC class.) The way I get the text from the textField is at textFieldDidEndEditing, and I add it to a mutableArray.
I then have different cell ids that get added when a button gets selected:
- (IBAction)addRow:(id)sender
{
NSInteger row = [self.rowArray cound];
[self.rowArray insertObject:#"anotherCell" atIndex:row];
NSIndexPath *indexPath = [NSindexPath indexPathForRow:row inSection:0];
[self.myTableView insertRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
(There is a textField in that cellID and I set the delegate to self.)
In textFieldDidEndEditing, I made an NSLog of textField.text, and when that method gets called from a textField that was there initially, it works as expected.
But when textFieldDidEndEditing gets called from the textField that's in the cell of anotherCell (the added cell), then the whole simulator freezes.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellID = [self.rowArray objectAtIndex:[indexPath row]];
customCell *cell = [tableView dequeuereusablecellwithidentifier:cellID forIndexPath:indexPath];
cell.name.delegate = self; // From cell that is initially there
cell.phoneNumber.delegate = self; // From the added cell
return cell;
}
(If this is confusing, or if you need more code, just let me know in the comments. Thanks)
Edit
- (void)textFieldDidEndEditing:(UITextField *)textField
{
if (textField.tag <= 9)
{
NSLog(#"%#", textField.text); // This works
}
UIView *superview = textField.superview;
while (![superview isMemberOfClass:[UITableViewCell class]]) {
superview = superview.superview;
}
CustomCellClass *cell = (CustomCellClass *)superview;
NSIndexPath *indexPath = [self.myTableView indexPathForCell:cell];
if (textField.tag >= 12)
{
if ([self.inputArray count] > indexPath.row) // So I won't get the error message of [__NSArrayM objectAtIndex:]: index 1 beyond bounds for empty array'
{
for (NSUInteger i = [self.inputArray count]; i < indexPath.row; i++) {
[self.inputArray insertObject:#"" atIndex:i];
NSLog(#"%lu", (unsigned long)i);
}
}
NSLog(#"%#", self.inputArray);
}
}
Your code is stuck in an infinite loop here:
while (![superview isMemberOfClass:[UITableViewCell class]]) {
superview = superview.superview;
}
because isMemberOfClass will return true only if the superview class is UITableViewCell, but NOT if it is a subclass of UITableViewCell. If you change isMemberOfClass to isKindOfClass, it should work. Check the Apple docs here.
I'm working on a messaging component of an iOS application. Each message is a row on my UITableView _messageTable I tried the following code in viewDidLoad, viewWillAppear and in viewDidAppear (messages are coming in from a background thread):
dispatch_async(dispatch_get_main_queue(), ^{
[_messageTable reloadData];
});
dispatch_async(dispatch_get_main_queue(), ^{
[self scrollToBottomOfTable];
});
-(void)scrollToBottomOfTable {
NSInteger rowCount = [_messageTable numberOfRowsInSection:0];
if (rowCount > 0) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow: rowCount-1 inSection: 0];
[_messageTable scrollToRowAtIndexPath: indexPath atScrollPosition: UITableViewScrollPositionBottom animated: YES];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _privateMessages.count;
}
This code works until there are about 20 or so rows. But when there are more messages, then it doesn't quite scroll all the way to the bottom. Is there some sort of limit? I'm ok with a view load delay if it means scrolling all the way to the bottom. Eventually I will implement some sort of message loading cap, but I would like to first understand and solve this issue.
EDIT
This is a table view within a view controller. I'm saving sent and received Message objects in a User object's array property (the person on the other end of the message conversation. app.hero is the user that is logged in, inheriting form the User object). The thing that doesn't make sense is that the code works perfectly for up to around 20 messages. Beyond that, it doesn't scroll all the way, but I can still manually scroll to the bottom as expected. The rest of the cell config code is :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
tableView.estimatedRowHeight = 20.0;
tableView.rowHeight = UITableViewAutomaticDimension;
Message *message = [_privateMessages objectAtIndex:indexPath.row];
static NSString *cellId = #"messageCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
cell.textLabel.numberOfLines=0;
}
return [self configureTableCell:cell forMessage:message];
}
- (UITableViewCell *)configureTableCell:(UITableViewCell *)cell forMessage:(Message *)message {
AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate];
if (message.sender == app.hero) {
cell.backgroundColor = [UIColor whiteColor];
cell.textLabel.textAlignment = NSTextAlignmentRight;
} else {
cell.backgroundColor = [UIColor colorWithRed:0 green:1 blue:0.2 alpha:0.3];
cell.textLabel.backgroundColor = [UIColor colorWithWhite:0 alpha:0];
cell.textLabel.textAlignment = NSTextAlignmentLeft;
}
cell.textLabel.text = message.content;
return cell;
}
I've determined that this issue has to do with cell height. By increasing tableView.estimatedRowHeight to 44.0, the table view scrolls flawlessly to the bottom. However, there remains an issue with when messages wrap beyond 1 line in a given cell. For each message longer than 1 line, the table scroll comes up a few more pixels short. Removing tableView.estimatedRowHeight altogether seems to result in similar behavior as setting it to say, 44.0. I want to say my original question is answered, but I'm still not sure how to make it scroll perfectly given the likelihood of multi-line cells.
EDIT - SOLUTION
The problem of incorrect scrolling is in fact solved by removing UITableViewAutomaticDimension and manually calculating the height in heightForRowAtIndexPath.
Here is a solution that works well with auto cell height sizing. It's quite a workaround, but this appears to be an Apple bug.
Set _manualScrolling=NO in viewDidLoad.
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
if (!decelerate) {
_manualScrolling = NO;
} else {
_manualScrolling = YES;
}
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
_manualScrolling = YES;
}
-(void)reloadTable {
dispatch_async(dispatch_get_main_queue(), ^{
[_messageTable reloadData];
});
dispatch_async(dispatch_get_main_queue(), ^{
[self scrollToBottomOfTable];
});
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (!_manualScrolling && ![self scrolledToBottom]) {
[self scrollToBottomOfTable];
}
}
-(BOOL)scrolledToBottom {
NSInteger rowCount = [_messageTable numberOfRowsInSection:0];
NSArray *visibleIndices = [_messageTable indexPathsForVisibleRows];
NSIndexPath *lastVisibleIndex = [visibleIndices lastObject];
NSIndexPath *lastIndex = [NSIndexPath indexPathForRow: rowCount-1 inSection: 0];
return lastVisibleIndex.row == lastIndex.row;
}
-(void)scrollToBottomOfTable {
NSInteger rowCount = [_messageTable numberOfRowsInSection:0];
if (!rowCount > 0) return;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow: rowCount-1 inSection: 0];
[_messageTable scrollToRowAtIndexPath: indexPath atScrollPosition: UITableViewScrollPositionBottom animated: YES];
}
So I have a deadline coming up for this project and I've been working hard on it and so I'm pretty tired right now. I don't know if I'm just being stupid and blind to what I'm doing wrong but I have a problem that I need help with.
So, I'm trying to implement a sort of "expanding tableview setup" (like in IOS 7 calendar where you tap on the start and end dates and a cell pops in with a date picker). I have two different cells that can be displayed under a tapped cell. It works perfectly except for the actual cell, when I insert a row the wrong cell is displayed. I'll give some context... I have two cells in section 0, when you tap on the first cell it inserts a cell below it that should be a picker cell. Instead it inserts the same call as in row 1 of the unmodified tableview.
Here is the relevant code:
#interface AddMealTableViewController ()
#property (nonatomic) BOOL datePickerEnabled;
#property (nonatomic) BOOL pickerEnabled;
#property (nonatomic, strong) NSIndexPath *datePickerIndexPath;
#property (nonatomic, strong) NSIndexPath *pickerIndexPath;
#end
#implementation AddMealTableViewController
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
switch (section) {
case 0:
return 2 + (self.datePickerEnabled) + (self.pickerEnabled);
break;
default:
return self.mealComponents.count;
break;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
switch (indexPath.section) {
case 0:
{
if (indexPath.row == 1) {
TimeCell *cell = [tableView dequeueReusableCellWithIdentifier:#"TimeCell"];
cell.timeLabel.text = #"Now";
cell.mealTypeLabel.text = self.selectedMealType;
return cell;
}
else if (indexPath == self.datePickerIndexPath) {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"DateCell"];
return cell;
}
else if (indexPath == self.pickerIndexPath) {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"PickerCell"];
return cell;
}
else {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MealTypeCell"];
cell.textLabel.text = #"Meal Type";
cell.detailTextLabel.text = self.selectedMealType;
return cell;
}
break;
}
default:
{
ComponentCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ComponentCell"];
if (!cell) {
cell = [ComponentCell new];
}
MealComponent *mc = self.mealComponents[indexPath.row];
[cell setUpWithComponent:mc];
return cell;
break;
}
}
return nil;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0) {
if (indexPath == self.datePickerIndexPath || indexPath == self.pickerIndexPath) {
return 200;
}
return self.tableView.rowHeight;
}
return 70;
}
- (void)toggleDatePickerForSelectedIndexPath:(NSIndexPath *)indexPath
{
[self.tableView beginUpdates];
NSArray *indexPaths = #[[NSIndexPath indexPathForRow:indexPath.row + 1 inSection:0]];
if (self.datePickerEnabled)
{
self.datePickerEnabled = NO;
self.datePickerIndexPath = nil;
[self.tableView deleteRowsAtIndexPaths:indexPaths
withRowAnimation:UITableViewRowAnimationFade];
}
else
{
self.datePickerIndexPath = indexPaths.lastObject;
self.datePickerEnabled = YES;
[self.tableView insertRowsAtIndexPaths:indexPaths
withRowAnimation:UITableViewRowAnimationFade];
}
[self.tableView endUpdates];
}
- (void)togglePickerForSelectedIndexPath:(NSIndexPath *)indexPath
{
[self.tableView beginUpdates];
NSArray *indexPaths = #[[NSIndexPath indexPathForRow:indexPath.row + 1 inSection:0]];
if (self.pickerEnabled)
{
self.pickerEnabled = NO;
self.pickerIndexPath = nil;
[self.tableView deleteRowsAtIndexPaths:indexPaths
withRowAnimation:UITableViewRowAnimationFade];
}
else
{
self.pickerIndexPath = indexPaths.lastObject;
self.pickerEnabled = YES;
[self.tableView insertRowsAtIndexPaths:indexPaths
withRowAnimation:UITableViewRowAnimationFade];
}
[self.tableView endUpdates];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
if ([cell.reuseIdentifier isEqual: #"TimeCell"]) {
[self toggleDatePickerForSelectedIndexPath:indexPath];
}
else if ([cell.reuseIdentifier isEqual: #"MealTypeCell"]) {
[self togglePickerForSelectedIndexPath:indexPath];
}
}
}
Any ideas? I really can't seem to put my finger on it.
why don't you change the height of date picker cell from 0 to 200 instead insert (or delete) the date picker cell. I think this is more simple.(This is what I'm used to implement that)
when [tableView didSelectRowAtIndexPath:] is called, you just call [tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic] to update cell.
You can managed the height of cell in [tableView heightForRowAtIndexPath:] you already know.
[edited]
I examine your code again.
change else if (indexPath == self.datePickefIndexPath) to else if([indexPath isEqual:self.datePickerIndexPath]) in [tableView:cellForRowAtIndexPath:]
There're many ways to handle this kind of things. You really don't need to insert or delete cell, just modify the cell height from 0 to the proper height. To do this, you can set a flag to check whether the cell's expanded or not.
I have more than 20 cells in my custom table view, in execution time 6 cells will be visible. Now i select the 4 th cell means, that 4th cell have to come in first position and 5th cell in 2nd position and so on. how to do this process, i tried like this.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MACalendarCustomCell *cell = (MACalendarCustomCell*) [tableView dequeueReusableCellWithIdentifier:[MACalendarCustomCell reuseIdentifier]];
if(cell == nil)
{
[[NSBundle mainBundle] loadNibNamed:#"MACalendarCustomCell" owner:self options:nil];
cell = customCell;
customCell = nil;
}
cell.lbl_CalendarTitle.text = [arr_CalendarTitle objectAtIndex:indexPath.row];
cell.lbl_CalendarSubTitle.text = [arr_CalendarSubTitle objectAtIndex:indexPath.row];
cell.lbl_calendarEventTime.text = [arr_CalendarEventTime objectAtIndex:indexPath.row];
cell.lbl_calendarDate.text = [arr_CalendarDate objectAtIndex:indexPath.row];
cell.lbl_CalendarMonth.text = [arr_CalendarMonth objectAtIndex:indexPath.row];
cell.lbl_CalendarYear.text = [arr_CalendarYear objectAtIndex:indexPath.row];
cell.img_BackGround.image = [UIImage imageNamed:#"calendar_Cell_Up.png"];
//here click event is occurred.
cell.btn_CollapseExpand.tag = indexPath.row;
[cell.btn_CollapseExpand addTarget:self action:#selector(method_Expand:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
ButtonPressed event calls
- (void)method_Expand:(UIButton*)sender
{
UITableViewCell *cell = (UITableViewCell *)sender.superview;
NSIndexPath *indexpath = [tbl_CalendarList indexPathForCell:cell];
[tbl_CalendarList moveRowAtIndexPath:[NSIndexPath indexPathForItem:indexpath.row inSection:indexpath.section] toIndexPath:[NSIndexPath indexPathForItem:0 inSection:indexpath.section]];
int_SelectedIndex = sender.tag;
NSLog(#"Selected Button : %ld",(long)int_SelectedIndex);
if ( int_TempSelectedIndex != int_SelectedIndex)
{
int_TempSelectedIndex = int_SelectedIndex;
}
else
{
int_TempSelectedIndex = -1;
}
[tbl_CalendarList reloadData];
}
Resizing the cell
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == int_TempSelectedIndex )
{
cellSize = 300;
isRowSelected[indexPath.row] = YES;
}
else
{
cellSize = 100;
isRowSelected[indexPath.row] = NO;
}
return cellSize;
}
Now i got Like this in simulator.
when i pressed it comes like this.
This selected cell should come to first position.
You can scroll your table view to that cell and you can specify that you want to scroll it on top when you select the cell:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
Hope this is what you are after.
In the method_Expand method after fetching the selected row you have to remove the object at the selected index and insert the removed object at 0 index.
Also you want to move the move next item to the second position
For that you have to increment the selected index and check if that index is with in the array bounds then remove that item and add it to the index 1;
- (void)method_Expand:(UIButton*)sender
UITableViewCell *cell = (UITableViewCell *)sender.superview;
NSIndexPath *indexpath = [tbl_CalendarList indexPathForCell:cell];
int nextIndex=indexpath.row+1;
// first remove the object
NSString *str=[arr_CalendarTitle objectAtIndex];
[arr_CalendarTitle removeObjectAtIndex:indexpath.row];
[arr_CalendarTitle insertObject:str atIndex:0];
//do the same to arr_CalendarEventTime,arr_CalendarDate,arr_CalendarMont etc
if([arr_CalendarTitle count]-1<nextIndex)// check if nextIndex within bounds to avoid crash
{
// remove next object and addit to the index 1 to all array
}
[tbl_CalendarList reloadData];
}
As i wrote in the comments:
Upon selection, move selected arr_CalendarTitle entry to the top of array and call reloadData() on tableView. Table view displays data as is sorted in arr_CalendarTitle.
moveRowAtIndexPath is not enough, must resort the array too.
So, before reloadData() call (in button click method), do this:
id object = [[[arr_CalendarTitle objectAtIndex:int_SelectedIndex] retain] autorelease];
[arr_CalendarTitle removeObjectAtIndex:int_SelectedIndex];
[arr_CalendarTitle insertObject:object atIndex:0];
For ARC you can use :
__autoreleasing id object = [arr_CalendarTitle objectAtIndex:int_SelectedIndex];
[arr_CalendarTitle removeObjectAtIndex:int_SelectedIndex];
[arr_CalendarTitle insertObject:object atIndex:0];
Since you have more than one array that holds data (only noticed that now) you must do this for every array thats holds data for tableView cells.
Use below method to scroll your tableview.
[tableview setContentOffset:CGPointMake(0, button.tag*tableview.rowHeight) animated:YES];
This method will make tableview scroll to specified point.
Change value of Y in CGPointMake according to your code.