如何在最后一个单元格上启动UITableView?

the*_*ory 26 iphone objective-c uitableview

在Apple的消息应用程序中,当您单击通讯员的名称并切换到对话的表格视图(每个消息都有气球)时,表格会一直滚动到最后.没有动画或任何东西,它就在那里.

同样,在Tweetie 2中,当您加载推文视图时,它会显示在您上次查看它的位置.没有动画到达那里,它就在那里,好像上面没有任何单元格被加载.

这些应用程序如何做到这一点?他们scrollToRowAtIndexPath:atScrollPosition:animated:在桌面控制器的某个地方打电话吗?如果是这样,他们怎么知道要传递给atScrollPosition:谁?它叫什么方法?

小智 57

scrollToRowAtIndexPath 应该管用.

viewWillAppear:,试试这个:

[theTableView reloadData];    
NSIndexPath* ip = [NSIndexPath indexPathForRow:rowNumberHere inSection:sectionNumberHere];
[theTableView scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionTop animated:NO];
Run Code Online (Sandbox Code Playgroud)

rowNumberHere 是要滚动到的数据源中的行号.

atScrollPosition只是UITableViewScrollPosition枚举中的一个值,可以确定屏幕上您想要显示的行号.但是,根据行数和您要滚动到的行,它可能没有区别.

reloadData:如果数据尚未加载,则放置避免异常viewWillAppear:.如果你把scrollToRowAtIndexPathviewDidAppear:,你不会需要的reloadData:,但你会看到表跳一点点,你说你不想要的.

编辑:@Theory,尝试更改您的代码如下...

[tableView reloadData];
int lastRowNumber = [tableView numberOfRowsInSection:0] - 1;
NSIndexPath* ip = [NSIndexPath indexPathForRow:lastRowNumber inSection:0];
[tableView scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionTop animated:NO];
Run Code Online (Sandbox Code Playgroud)

请注意numberOfRowsInSection返回行数,而不是最后一行(行数 - 1).

  • 在iOS 7的`viewWillAppear`中,如果`self.parentViewController`是`UINavigationController`,`self.view`仍然没有调整大小.所以,我想出了这个[解决方案:'UITableView`在加载后滚动到底部](http://stackoverflow.com/a/19367073/242933). (2认同)

Dee*_*olu 9

您可以在TableViewController的-viewWillAppear:方法中调用-scrollToRowAtIndexPath:atScrollPosition:animated.

atScrollPosition:允许您设置rowAtIndexPath出现的单元格的位置.有四种选择:

UITableViewScrollPositionTop - 将您的单元格放在视图的顶部

UITableViewScrollPositionMiddle - 在视图中居中您的单元格

UITableViewScrollPositionBottom - 将您的单元格放在底部

UITableViewScrollPositionNone - 使用此设置将在用户视图中以最小的滚动/移动位于单元格中.

三种情况下的行为有所不同: -

如果单元格已在视图中,则不执行任何操作.

如果单元格位于当前视图上方,则会将单元格滚动到视图顶部.

如果单元格位于当前视图下方,则会将单元格滚动到视图的底部.


Gen*_*ani 9

Swift 3Swift 4中回答@DyingCactus :

    let lastRow: Int = self.tableView.numberOfRows(inSection: 0) - 1
    let indexPath = IndexPath(row: lastRow, section: 0);
    self.tableView.scrollToRow(at: indexPath, at: .top, animated: false)
Run Code Online (Sandbox Code Playgroud)


the*_*ory 7

按照DyingCactus上面的回复,我将这个方法添加到我的控制器:

-(void)viewWillAppear:(BOOL)animated {
      [self.tableView reloadData];    
      NSIndexPath* ip = [NSIndexPath indexPathForRow:[self.tableView numberOfRowsInSection:0] - 1 inSection:0];
      [self.tableView scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionTop animated:NO];
}
Run Code Online (Sandbox Code Playgroud)

现在它可以工作,正是我想要的.谢谢!

  • 大.您可能还想添加零行检查,并且在这种情况下不调用滚动,除非您的tableview始终至少有一行. (2认同)

Raf*_*fAl 7

我正在使用autolayout,但没有一个答案适合我.这是我最终解决的解决方案:

@property (nonatomic, assign) BOOL shouldScrollToLastRow;


- (void)viewDidLoad
{
    [super viewDidLoad];

    _shouldScrollToLastRow = YES;
}


- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];

    // Scroll table view to the last row
    if (_shouldScrollToLastRow)
    {
        _shouldScrollToLastRow = NO;
        [self.tableView setContentOffset:CGPointMake(0, CGFLOAT_MAX)];
    }
}
Run Code Online (Sandbox Code Playgroud)