scrollToRowAtIndexPath 错误

Posted

技术标签:

【中文标题】scrollToRowAtIndexPath 错误【英文标题】:error with scrollToRowAtIndexPath 【发布时间】:2012-01-18 21:35:52 【问题描述】:

我在使用我的使用 tableviews 的应用程序时遇到错误,错误如下所示。

2012-01-19 10:19:51.442 bcode[1176:207] *** Terminating app due to uncaught exception 'NSRangeException', reason: '-[UITableView scrollToRowAtIndexPath:atScrollPosition:animated:]: row (3) beyond bounds (3) for section (0).'
*** First throw call stack:
(0x16c3052 0x1920d0a 0x166ba78 0x166b9e9 0x68a136 0x3bfdf 0x6c2fbf 0x6c32d4 0x6c35d7 0x6d2666 0x87890e 0x878c17 0x878c86 0x62c499 0x62c584 0x2718e00 0x13614f0 0x15fa833 0x15f9db4 0x15f9ccb 0x1d05879 0x1d0593e 0x5fba9b 0x2838 0x2795 0x1)
terminate called throwing an exception(gdb) 

NSRangeException,-[UITableView scrollToRowAtIndexPath:atScrollPosition:animated:] 第 (3) 行超出第 (0) 节的边界 (3)。

发生的情况是,当用户向下钻取我的导航视图时,他们可以从每个视图的 tableview 中选择一个单元格,稍后将用于构建搜索字符串。

但是,如果他们犯了错误,我允许他们返回并更改他们的选择。当用户更改父视图的值然后仅当先前的选择超出条目数时才进入子视图时会发生此错误在当前的 tableview 中..

通常这不会是一个大问题,但是,在 viewDidAppear 内部,我正在调用一个滚动到先前选择的单元格的方法......这显然是破坏应用程序并给我错误的原因。

- (void)viewDidAppear:(BOOL)animated

    [super viewDidAppear:animated];
    //Scroll to previously selected value
    [self.tableView scrollToRowAtIndexPath:oldCheckedIndexPath  atScrollPosition:UITableViewScrollPositionMiddle animated:YES];

我怎样才能阻止它执行我已经尝试了大约 100 种不同的 if 语句在父视图和子视图中捕获新的 indexpath 并再次检查 oldselected indexpaths 然后设置

oldCheckedIndexPath = nil;

但无论如何它总是会搞砸。

【问题讨论】:

【参考方案1】:

干净的方式,假设self是tableView数据源:

查看tableview中的section数量:

if ( [self numberOfSectionsInTableView:self.tableView]
                                     > oldCheckedIndexPath.section 

并检查该部分中的行数:

  && [self tableView:self.tableView numberOfRowsInSection:
          oldCheckedIndexPath.section] > oldCheckedIndexPath.row )
   
      [self.tableView scrollToRowAtIndexPath: // etc etc etc

或者,快速破解:

@try 
    [self.tableView scrollToRowAtIndexPath: // etc etc etc 

@catch ( NSException *e )

    NSLog(@"bummer: %@",e);

【讨论】:

哦,是的!不敢相信我没想到这一点.. whicked !工作完美!哈哈,在过去的 5 个小时里,老实说,我一直在绞尽脑汁试图破解这个!完美的!非常感谢! +1 为幽默的 NSLog! BTW @C.Johns 不使用 try ... catch 方法 - 这是非常糟糕的做法(至少在 C 中 - Java 完全是另一回事......)。 哈哈,是的,我笑了。@jrtc27,是的,我使用了正确构造的 if 语句……它工作得很好。 @C.Johns:很好用。甚至比调用您自己的委托方法更好,可能是查看实际数据。 [self.categories count] 更短,可能同样有效。 好吧,很酷会做,一旦我弄清楚为什么在某些情况下附件刻度没有被移除,我很快就会玩一玩..再次感谢您的帮助! :)【参考方案2】:

受到公认答案的启发:

目标-C:

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
if ([self numberOfSectionsInTableView:self.tableView] > indexPath.section && [self tableView:self.tableView numberOfRowsInSection:indexPath.section] > indexPath.row) 
    [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];

斯威夫特:

let indexPath = IndexPath(row: rowToScroll, section: sectionToScroll) 
if (self.tableView.numberOfSections > indexPath.section && self.tableView.numberOfRows(inSection: indexPath.section) > indexPath.row ) 
    self.tableView.scrollToRow(at: IndexPath(row: rowToScroll, section: sectionToScroll), at: .top, animated: true) 

【讨论】:

【参考方案3】:

在调用 scrollToRowAtIndexPath 之前,我通过另一个选项解决了这个问题:此方法使用 [yourtableviewobject reloadData]; 重新加载您的 tableview,然后调用:

NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:([messages count] - 1) inSection:0];
[objTableView scrollToRowAtIndexPath:scrollIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];

【讨论】:

【参考方案4】:

我收到此错误是因为我试图滚动到空 tableView 的第 0 行第 0 部分。确保您的 tableData.count > 0。

【讨论】:

以上是关于scrollToRowAtIndexPath 错误的主要内容,如果未能解决你的问题,请参考以下文章

insertRowsAtIndexPaths: with scrollToRowAtIndexPath: 导致 UITableView 部分被错误地隐藏

UITableView scrollToRowAtIndexPath

在 iOS 8 上,scrollToRowAtIndexPath 无法正确滚动到底部

scrollToRowAtIndexPath 在标题部分内滚动

scrollToRowAtIndexPath 上非常奇怪的 UITableViewController.tableview 行为

求助关于scrollToRowAtIndexPath 不执行