63

How can I scroll the table's cell to specific position ? I have a table which shows 3 rows (according to height). what I want is if I click on 1st row than according to table's height the 1st row should scroll and get new position (center) and same for other rows. I tried contenOffset but did not work..

EDITED :

In short some thing like data picker when we select any row in picker the row scrolls to the center.

Thanks..

Code cracker
  • 3,105
  • 6
  • 37
  • 67
Maulik
  • 19,348
  • 14
  • 82
  • 137
  • If I scroll down to the tenth item in the list and my display is showing item 10, 11, 12. Are you saying if I click the first row (which is item 10) to center item 10 on the screen effectively displaying item 9, 10, 11? – Black Frog May 02 '11 at 11:21
  • ya... similar to the data picker... – Maulik May 02 '11 at 11:31

8 Answers8

141

it should work using - (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated using it this way:

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[yourTableView scrollToRowAtIndexPath:indexPath 
                     atScrollPosition:UITableViewScrollPositionTop 
                             animated:YES];

atScrollPosition could take any of these values:

typedef enum {
UITableViewScrollPositionNone,
UITableViewScrollPositionTop,
UITableViewScrollPositionMiddle,
UITableViewScrollPositionBottom
} UITableViewScrollPosition;
starball
  • 20,030
  • 7
  • 43
  • 238
Fran Sevillano
  • 8,103
  • 4
  • 31
  • 45
  • will this method call when I select the row ? – Maulik May 02 '11 at 11:29
  • No, it will select a row when it gets called. It will NOT get called when you select a row. There is a subtle difference. – Fran Sevillano May 02 '11 at 11:36
  • I want table to scroll when I select the row... how can I set the cell's contentOffset according to the current table's height ? – Maulik May 02 '11 at 11:42
  • When you select a row, the method `- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath` in `UITableViewDelegate` gets called, so place a call to the `scrollToRowAtIndexPath` in that method. I strongly suggest you to read the `Table View Programming Guide for iOS` as well as the `UITableView`reference and `UITableViewDelegate` reference, you will find them very useful, and after all, that is what documentation is for – Fran Sevillano May 02 '11 at 11:57
  • This should be the selected answer. – rtcarlson Jun 20 '16 at 18:49
18

Swift 4.2 version:

let indexPath:IndexPath = IndexPath(row: 0, section: 0)
self.tableView.scrollToRow(at: indexPath, at: .none, animated: true)

Enum: These are the available tableView scroll positions - here for reference. You don't need to include this section in your code.

public enum UITableViewScrollPosition : Int {

case None
case Top
case Middle
case Bottom
}

DidSelectRow:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    let theCell:UITableViewCell? = tableView.cellForRowAtIndexPath(indexPath)

    if let theCell = theCell {
        var tableViewCenter:CGPoint = tableView.contentOffset
        tableViewCenter.y += tableView.frame.size.height/2

        tableView.contentOffset = CGPointMake(0, theCell.center.y-65)
        tableView.reloadData()
    }

}
Hardik Thakkar
  • 15,269
  • 2
  • 94
  • 81
odemolliens
  • 2,581
  • 2
  • 32
  • 34
17
[tableview scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO];

This will take your tableview to the first row.

Praveen S
  • 10,355
  • 2
  • 43
  • 69
16

finally I found... it will work nice when table displays only 3 rows... if rows are more change should be accordingly...

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{    
    return 1;
}


// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView 
 numberOfRowsInSection:(NSInteger)section
{  
    return 30;
}

- (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil)
    {         
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault    
                                       reuseIdentifier:CellIdentifier] autorelease];
    }

    // Configure the cell.
    cell.textLabel.text =[NSString stringWithFormat:@"Hello roe no. %d",[indexPath row]];

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell * theCell = (UITableViewCell *)[tableView     
                                              cellForRowAtIndexPath:indexPath];

    CGPoint tableViewCenter = [tableView contentOffset];
    tableViewCenter.y += myTable.frame.size.height/2;

    [tableView setContentOffset:CGPointMake(0,theCell.center.y-65) animated:YES];
    [tableView reloadData]; 
 }
Ed Chapel
  • 6,842
  • 3
  • 30
  • 44
Maulik
  • 19,348
  • 14
  • 82
  • 137
  • 2
    Just a comment - hardcoding values into code is bad practice. Here I see you put [tableView setContentOffset:CGPointMake(0,theCell.center.y-65) animated:YES]; - the -65 is bad. Consider using code for 65 like theCell.frame.size.height for example. – GeneCode Feb 13 '16 at 00:17
  • @Rocotilos yes I agree. But I have clearly mentioned that "it will work nice when table displays only 3 rows... if rows are more change should be accordingly... " It was just an example code. Also I have used this table as UIPicker. – Maulik Feb 15 '16 at 07:17
  • 1
    It's not working, beside there is better solution than that. – Ali Omari Nov 24 '16 at 11:02
  • we can use a counter value to store the number of row we want to display and if we want to display more row we should change the counter value – Ahmed Sahib Feb 07 '17 at 10:12
15

Use [tableView scrollToRowAtIndexPath:indexPath atScrollPosition:scrollPosition animated:YES]; Scrolls the receiver until a row identified by index path is at a particular location on the screen.

And

scrollToNearestSelectedRowAtScrollPosition:animated:

Scrolls the table view so that the selected row nearest to a specified position in the table view is at that position.

visakh7
  • 26,380
  • 8
  • 55
  • 69
  • and how can I calculate the height of table ? means do I have to calculate the height of table with all rows or just visible rows ? – Maulik May 02 '11 at 11:22
  • or say , how can I set the cell's contentOffset according to the current table's height ? do I need to calculate the table's height with all rows or just visible rows ? – Maulik May 02 '11 at 11:43
  • if its standard table cell its height will be 44. – visakh7 May 02 '11 at 11:46
1

It is worth noting that if you use the setContentOffset approach, it may cause your table view/collection view to jump a little. I would honestly try to go about this another way. A recommendation is to use the scroll view delegate methods you are given for free.

Stephen Paul
  • 2,762
  • 2
  • 21
  • 25
0

Simply single line of code:

self.tblViewMessages.scrollToRow(at: IndexPath.init(row: arrayChat.count-1, section: 0), at: .bottom, animated: isAnimeted)
Mr.Javed Multani
  • 12,549
  • 4
  • 53
  • 52
0

In case, your table view only has one row and one section, you also can use following approach

 challengeInfoTableView.scrollRectToVisible(challengeInfoCell.challengeDescriptionTextView!.frame, animated: false)

In this case, you can directly scroll to the correct text field, text view, label etc.

Nazar Medeiros
  • 437
  • 4
  • 10