我在cellForRowAtIndexpath中添加了selectRowAtIndexPath来标记上一个选定的行但是如果滚动tablview它崩溃了

时间:2013-08-23 12:44:41

标签: iphone ios uitableview

我正在制作一个自定义的UITableView菜单选择器组件。每次我选择一个特定的行时,我都会保存这行的indexpath,所以下次当用户选择另一行时,人们就可以知道他之前选择的行了。所以我把它添加到了cellForRowAtIndexpath

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];

    cell.textLabel.text = self.left[indexPath.row][@"name"];
    [tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:[[[NSUserDefaults standardUserDefaults] objectForKey:kPreviousSelectedRow] integerValue] inSection:0] animated:YES scrollPosition:UITableViewScrollPositionNone];
    cell.selectionStyle = UITableViewCellSelectionStyleGray;
    cell.textLabel.highlightedTextColor = [UIColor grayColor];
    return cell;
}

当用户选择另一行时,将此行保存为:[[[NSUserDefaults standardUserDefaults] objectForKey:kPreviousSelectedRow],以便下次他可以看到他之前选择的行。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:indexPath.row] forKey:kPreviousSelectedRow];
}

崩溃日志:index是[[[NSUserDefaults standardUserDefaults] objectForKey:kPreviousSelectedRow] integerValue],count是numberOfRows。正如你所看到的,它不应该超出范围。我不知道[0 ... 6]来自哪里。

2013-08-23 21:01:26.107 [17605:c07] index:10, count:14
2013-08-23 21:01:26.173[17605:c07] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 7 beyond bounds [0 .. 6]'

编辑:如果我慢慢滚动tableview,它不会崩溃,如果我快速滚动它,它会崩溃。什么?

6 个答案:

答案 0 :(得分:2)

您遇到了崩溃,因为在这个确切的时间您没有指定索引的单元格,因为您只是在- (UITableViewCell*)tableView:cellForRowAtIndexPath:

中准备它

为了获得您期望从selectRowAtIndexPath:移出- (UITableViewCell*)tableView:cellForRowAtIndexPath:的行为,并将其置于您正在更新UITableView-(void)viewDidLoad或您调用的地方的其他方法中例如-(void)reloadTable

答案 1 :(得分:1)

您的应用正在崩溃,因为它正在尝试选择当前可能不可见的行。当数据可能尚未完全可用时,您尝试在数据源方法“cellForRowAtIndexPath”中选择一行。这就是你得到越界错误的原因。

对于您的具体示例,您可以尝试在更新值之前选择“didSelectRowAtIndexPath”中之前选择的行,因为您的数据已经显示,所以它不会崩溃。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{   
    [tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:[[[NSUserDefaults standardUserDefaults] objectForKey:kPreviousSelectedRow] integerValue] inSection:0] animated:YES scrollPosition:UITableViewScrollPositionNone];
    [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:indexPath.row]     forKey:kPreviousSelectedRow];
}

答案 2 :(得分:1)

SVGreg是对的。您应该在另一个方法中使用单元格。但viewDidLoad不是最佳选择。您可以尝试这种有用的委托方法

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {

    [tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:[[[NSUserDefaults standardUserDefaults] objectForKey:kPreviousSelectedRow] integerValue] inSection:0] animated:YES scrollPosition:UITableViewScrollPositionNone];
    cell.selectionStyle = UITableViewCellSelectionStyleGray;
}

答案 3 :(得分:0)

[tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:[[[NSUserDefaults standardUserDefaults] objectForKey:kPreviousSelectedRow] integerValue] inSection:0] animated:YES scrollPosition:UITableViewScrollPositionNone];

不应在cellForRowAtIndexpath内。

indexPath获取didSelectRowAtIndexPath,每次用户选择一个小区时都会触发该-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 。 如果要在用户取消选择单元格或选择其他单元格时触发另一种方法,请使用

{{1}}

答案 4 :(得分:0)

您可以创建一个容量等于行数的数组。用NO BOOL值(实际上是[NSnumber numberWithBool:]来填充它,因为它们需要是对象)。

然后在

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

更改位置indexPath.row,

处对象的值

并在

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

检查数组中的BOOL值是否设置为YES然后选择单元格。 (cell.selected = YES)

您可以加倍努力,使用自定义选择样式制作自定义单元格,然后在单元格上创建一个方法,该方法将应用您选择的设计并在cellForRowAtIndexPath中调用该方法。

答案 5 :(得分:0)

哦,我只是将selectRowAtindex替换为layoutsubview,现在它不会崩溃。感谢SVGreg的提示。