如何将UITableView滚动到特定位置

63

我该如何将表格的单元格滚动到特定位置?我有一个表格,显示3行(根据高度)。我想做的是,如果我点击第一行,根据表格的高度,第一行应该滚动并获得新位置(中心),其他行也一样。我尝试了contenOffset但没有成功。

编辑:

简而言之,就像数据选择器一样,当我们选择选择器中的任何行时,该行会滚动到中心。

谢谢..


如果我滚动到列表中的第十个项目,并且我的显示屏正在显示项目10、11、12。你是说,如果我点击第一行(即项目10),将项目10居中在屏幕上,从而有效地显示项目9、10、11? - Black Frog
与数据选择器类似的ya... - Maulik
8个回答

141

使用- (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated方法应该可以解决问题,用法如下:

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

atScrollPosition 可以取以下任意值:

typedef enum {
UITableViewScrollPositionNone,
UITableViewScrollPositionTop,
UITableViewScrollPositionMiddle,
UITableViewScrollPositionBottom
} UITableViewScrollPosition;

当我选择行时,这个方法会被调用吗? - Maulik
不,当它被调用时,它会选择一行。但当你选择一行时,它不会被调用。这有微妙的区别。 - Fran Sevillano
我想在选择行时使表格滚动... 我该如何根据当前表格的高度设置单元格的contentOffset? - Maulik
当您选择一行时,UITableViewDelegate中的方法- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath将被调用,因此在该方法中调用scrollToRowAtIndexPath。我强烈建议您阅读iOS表视图编程指南以及UITableView参考和UITableViewDelegate参考,您会发现它们非常有用,毕竟,这就是文档的用途。 - Fran Sevillano
这应该是被选中的答案。 - rtcarlson

18

Swift 4.2版本:

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

枚举: 这是可用的tableView滚动位置,仅供参考。您无需在代码中包含此部分。

public enum UITableViewScrollPosition : Int {

case None
case Top
case Middle
case Bottom
}

DidSelectRow:

->

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()
    }

}

17
[tableview scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO];

这将把您的表格视图滚动到第一行。


@Parveen 谢谢,这对我很有帮助。 - Ranjit Bisht
针对Xamarin开发人员的答案:tblRecord.ScrollRectToVisible(CoreGraphics.CGRect.FromLTRB(0, 0, 1, 1), true); - Ranjit Bisht

16

最后我发现......当表格仅显示3行时,它可以很好地工作......如果行数更多,则需要相应地进行更改......

- (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]; 
 }

2
只是一个评论-将值硬编码到代码中是不良实践。在这里我看到你放置了[tableView setContentOffset:CGPointMake(0,theCell.center.y-65) animated:YES]; -65是不好的。考虑使用像theCell.frame.size.height这样的代码来代替65。 - GeneCode
@Rocotilos 是的,我同意。但是我已经清楚地提到了“当表格只显示3行时,它会很好地工作...如果行数更多,应相应进行更改...”这只是一个示例代码。此外,我已将此表用作UIPicker。 - Maulik
1
它不起作用,此外还有比那更好的解决方案。 - Ali Omari
我们可以使用计数器变量来存储我们想要显示的行数,如果我们想要显示更多的行,就应该改变计数器的值。 - Ahmed Sahib

15

使用 [tableView scrollToRowAtIndexPath:indexPath atScrollPosition:scrollPosition animated:YES]; 可以滚动表视图使得指定的行在屏幕上的特定位置可见。

还有...

scrollToNearestSelectedRowAtScrollPosition:animated:

滚动表格视图以使离指定位置最近的选中行位于该位置。


如何计算表格的高度?是要计算所有行的高度还是只计算可见行的高度? - Maulik
我应该如何根据当前表格的高度设置单元格的contentOffset?我需要计算所有行还是只计算可见行的表格高度? - Maulik
如果它是标准表格单元格,其高度将为44。 - visakh7

1
值得注意的是,如果您使用setContentOffset方法,可能会导致您的表视图/集合视图跳动一下。我建议您尝试另一种方法。一个建议是使用您免费获得的滚动视图委托方法。

0

只需一行代码:

self.tblViewMessages.scrollToRow(at: IndexPath.init(row: arrayChat.count-1, section: 0), at: .bottom, animated: isAnimeted)

0
如果你的表视图只有一行和一节,你也可以使用以下方法。
 challengeInfoTableView.scrollRectToVisible(challengeInfoCell.challengeDescriptionTextView!.frame, animated: false)

在这种情况下,您可以直接滚动到正确的文本字段、文本视图、标签等。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接