Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I added selectRowAtIndexPath in cellForRowAtIndexpath to mark previous selected row but if scroll tablview it crashs

I am making a custom UITableView menu selector component. Every time I selected a specific row, I save this row's indexpath, so the next time when a user to select another row, people can know his previous selected row. So I added this into 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;
}

and when the user select another row, save this row to :[[[NSUserDefaults standardUserDefaults] objectForKey:kPreviousSelectedRow], so next time he can see his previous selected row.

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

The crash log: index is [[[NSUserDefaults standardUserDefaults] objectForKey:kPreviousSelectedRow] integerValue] and count is numberOfRows. As you can see, it shouldn't out of bounds. I don't know where the [0...6] come from.

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]'

EDITED:And If I scroll the tableview slow, it won't crash, if I scroll it fast, it crashes. what?

like image 833
yong ho Avatar asked Oct 04 '22 03:10

yong ho


3 Answers

You get a crash because at this exact time you have no cell with specified index because you're just preparing it inside your - (UITableViewCell*)tableView:cellForRowAtIndexPath:

To get behaviour you're expecting move selectRowAtIndexPath: out of - (UITableViewCell*)tableView:cellForRowAtIndexPath: and place it inside another method where you're updating your UITableView: -(void)viewDidLoad or where you call -(void)reloadTable for example

like image 126
SVGreg Avatar answered Oct 27 '22 11:10

SVGreg


Your app is crashing because it is trying to select a row that it may not be currently visible. You are trying to select a row in your data source method "cellForRowAtIndexPath" when the data may not be completely available yet. That is why you get the out of bounds error.

For your specific example, you could try to select the previously selected row inside your "didSelectRowAtIndexPath" before you update the value, it will not crash here since your data has been already displayed.

- (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];
}
like image 1
Callistino Avatar answered Oct 27 '22 09:10

Callistino


SVGreg was right. You should work with cell inside another method. But viewDidLoad not best option. You may try this useful method of delegate

- (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;
}
like image 1
Y.Minaev Avatar answered Oct 27 '22 11:10

Y.Minaev