UITableView 滚动到特定位置

8
我正在使用 iPhone SDK 3.1.3。我有一个 UITableViewController 从另一个控制器获取数据。表视图被添加为主视图的子视图,但其框架设置为不可见。通过点击按钮,更新表视图框架并使其滑动到主视图上方。
表视图已出现,我滚动到最后一行。如果我选择了最后一行,我将使用更多数据重新加载表格视图。表格用更多数据进行了更新。除了滚动位置始终在顶部之外,一切正常。
我需要滚动位置是我单击以加载更多数据的最后一行。我保存滚动位置并在加载更多数据后调用以下代码。它可以执行,但滚动位置始终在顶部。
 [theTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:savedScrollPosition inSection:0] atScrollPosition:savedScrollPosition animated:NO];

以上似乎没有效果。 ViewWillAppear: ViewDidAppear: 不会触发,并且我被告知,如果视图控制器是在代码中实例化的,这种情况就不会触发。请帮助我弄清楚如何在重新加载表格后([theTableView reloadData]),在所点击的行处设置滚动位置的时间和方式。

重新加载表格视图和滚动的代码

 ////performAction will notify the tableviewcontroller which will result in didPerformAction being called
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
     if (indexPath.row == lastRow)
     {
       savedScrollPosition = lastRow;
       //perform the action
       [controller performAction];
     }
}

- (void) didPerformAction:(NSNotification *)obj
{
  [theTableView reloadData];
  [theTableView
     scrollToRowAtIndexPath: [NSIndexPath indexPathForRow:savedScrollPosition inSection:0]
     atScrollPosition:UITableViewScrollPositionBottom 
     animated:NO];
}
3个回答

30

这似乎起到了作用。

[theTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:savedScrollPosition inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
CGPoint point = theTableView.contentOffset;
point .y -= theTableView.rowHeight;
theTableView.contentOffset = point;

3
这个语句中的 savedScrollPosition 是什么意思? - Pradumna Patil

10

如果你可以插入行而不是调用reloadData,界面会更好看,滚动位置也会保持不变。

[theTableView beginUpdates];
[theTableView insertRowsAtIndexPaths:indexPaths withRowAnimation:animation];
// make sure the dataSource will return new rows before calling endUpdates
[theTableView endUpdates];

你可以使用UIScrollView的滚动代替UITableView的滚动:

savedOffset = [theTableView contentOffset];

然后进行恢复:

[theTableView setContentOffset:savedOffset];

哦,谢谢。我刚刚发布了答案,大部分与你的相同,设置contentOffset。感谢你的插入行提示。 - Dave

0

如果这是实际的代码,并且假设 theTableView 在那里不是 nil,那么你应该会收到一个警告,说“可能无法响应...”,因为 scrollToRowAtIndexPath 拼写错误。

其次,atScrollPosition 参数需要一个 UITableViewScrollPosition 枚举值,表示您希望目标行在屏幕上定位的位置。

试试这个:

[theTableView scrollToRowAtIndexPath:
                [NSIndexPath indexPathForRow:savedScrollPosition inSection:0]
                atScrollPosition:UITableViewScrollPositionBottom 
                animated:NO];

抱歉,那是一个打字错误。我已经进行了编辑。我不想滚动到底部。我需要滚动到我点击的行,这有点像中间但不总是中间。尽管如此,我尝试了这个方法,但奇怪的是它仍然停留在顶部。 - Dave
显示调用该方法的位置。在调用之前放置NSLogs,显示savedScrollPosition的值。atScrollPosition不是指行号,而是指其在屏幕上的当前相对位置。 - user121301
reloadData是否被调用并且您能看到额外的数据?在reloadData行之后记录savedScrollPosition的值,并确认它是之前选中的那一行。 - user121301
我正在阅读有关tableview边界的内容,如果高度超过实际视图边界,则无法滚动。我尝试将高度设置为较低的值,但仍然看到相同的行为。 - Dave
谢谢!虽然看起来很奇怪,但我不得不设置contentOffSet。我已经添加了我的答案。 - Dave
显示剩余2条评论

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