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?
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
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];
}
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With