34

在我正在开发的应用程序中,我有一个普通样式的 UITableView,它可以包含一个包含零行的部分。我希望能够使用 scrollToRowAtIndexPath:atScrollPosition:animated: 滚动到此部分,但由于缺少子行,当我尝试滚动到此部分时出现错误。

Apple 的日历应用程序能够做到这一点,如果您在列表视图中查看您的日历,并且您的日历中没有今天的事件,则会为今天插入一个空白部分,您可以使用工具栏中的“今天”按钮滚动到它在屏幕底部。据我所知,Apple 可能正在使用自定义的 UITableView,或者他们正在使用私有 API ...

我能想到的唯一解决方法是在 0 像素高的地方插入一个空的 UITableCell 并滚动到该位置。但据我了解,拥有不同高度的单元格对于滚动性能确实很不利。无论如何,我还是会尝试一下,也许性能不会太差。

更新

由于似乎没有解决方案,我已经向苹果提交了一个错误报告。如果这也影响到您,如果您希望更快地解决此问题,请提交 rdar://problem/6263339(打开雷达链接)的副本。

更新#2

我对这个问题有一个不错的解决方法,看看我下面的答案。

4

6 回答 6

122

更新:看起来这个错误在 iOS 3.0 中已修复。您可以使用以下内容NSIndexPath滚动到包含 0 行的部分:

[NSIndexPath indexPathForRow:NSNotFound inSection:section]

对于仍在使用 2.x SDK 维护项目的任何人,我将把我原来的解决方法留在这里。


找到了一个不错的解决方法:

CGRect sectionRect = [tableView rectForSection:indexOfSectionToScrollTo];
[tableView scrollRectToVisible:sectionRect animated:YES];

上面的代码将滚动表格视图,以便所需部分可见,但不一定位于可见区域的顶部或底部。如果要滚动以使该部分位于顶部,请执行以下操作:

CGRect sectionRect = [tableView rectForSection:indexOfSectionToScrollTo];
sectionRect.size.height = tableView.frame.size.height;
[tableView scrollRectToVisible:sectionRect animated:YES];

根据需要修改 sectionRect 以将所需部分滚动到可见区域的底部或中间。

于 2008-12-08T22:07:18.607 回答
7

如果您的部分没有行,请使用此

let indexPath = IndexPath(row: NSNotFound, section: section)
tableView.scrollToRow(at: indexPath, at: .middle, animated: true)
于 2019-04-25T06:44:35.120 回答
4

这是一个老问题,但 Apple 仍然没有添加任何有助于或修复该部分没有行的崩溃错误的任何内容。

对我来说,我确实需要在添加时将新部分滚动到中间,所以我现在使用以下代码:

if (rowCount > 0) {
    [self.tableView scrollToRowAtIndexPath: [NSIndexPath indexPathForRow: 0 inSection: sectionIndexForNewFolder] 
                          atScrollPosition: UITableViewScrollPositionMiddle
                                  animated: TRUE];
} else { 
    CGRect sectionRect = [self.tableView rectForSection: sectionIndexForNewFolder];
    // Try to get a full-height rect which is centred on the sectionRect
    // This produces a very similar effect to UITableViewScrollPositionMiddle.
    CGFloat extraHeightToAdd = sectionRect.size.height - self.tableView.frame.size.height;
    sectionRect.origin.y -= extraHeightToAdd * 0.5f;
    sectionRect.size.height += extraHeightToAdd;
    [self.tableView scrollRectToVisible:sectionRect animated:YES];
}

希望你喜欢它——正如你所看到的,它基于 Mike Akers 的代码,但是计算滚动到中间而不是顶部。谢谢迈克-你是明星。

于 2012-05-28T10:01:45.513 回答
3

一个 Swift 的方法:

if rows > 0 {
    let indexPath = IndexPath(row: 0, section: section)
    self.tableView.setContentOffset(CGPoint.zero, animated: true)
    self.tableView.scrollToRow(at: indexPath, at: .top, animated: true)
}

else {
    let sectionRect : CGRect = tableView.rect(forSection: section)
    tableView.scrollRectToVisible(sectionRect, animated: true)
}
于 2018-01-10T05:16:53.317 回答
2

由于使用:

[NSIndexPath indexPathForRow:NSNotFound inSection:EXAMPLE]

在 Xcode 11.3.1(iOS 模拟器 - 13.3)中为我损坏了我决定使用:

NSUInteger index = [self.sectionTypes indexOfObject:@(EXAMPLE)];
if (index != NSNotFound) {
    CGRect rect = [self.tableView rectForSection:index];
    [self.tableView scrollRectToVisible:rect animated:YES];
}
于 2020-02-24T11:32:10.257 回答
-1

我认为空白行可能是去那里的唯一方法。是否可以重新设计 UI,使“空”行可以显示有用的内容?

我说试试看,看看性能如何。他们对在列表项中使用透明子视图给出了非常可怕的警告,而且我发现它在我的应用程序中并没有那么重要。

于 2008-10-01T21:30:07.857 回答