I added selectRowAtIndexPath to cellForRowAtIndexpath to mark the previous selected row, but if I scroll through the tablview, it will crash

I am creating a custom UITableView menu control. Each time I select a specific row, I save this row index path, so the next time the user selects another row, people can find out their previous selected row. So I added this to 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 selects another row, save this row: [[[[NSUserDefaults standardUserDefaults] objectForKey: kPreviousSelectedRow], so the next time he sees his previous selected row.

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

Failure log: index [[[[NSUserDefaults standardUserDefaults] objectForKey: kPreviousSelectedRow] integerValue], and count is numberOfRows. As you can see, this should not go beyond. I do not know where [0 ... 6] comes 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 through the table view slowly, it will not work; if I scroll through it quickly, it will work. what?

+4
source share
6 answers

You get a failure because at this exact time you do not have a cell with the specified index, because you just cook it in your - (UITableViewCell*)tableView:cellForRowAtIndexPath:

To get the behavior you expect, move selectRowAtIndexPath: from - (UITableViewCell*)tableView:cellForRowAtIndexPath: and put it in another method where you update your UITableView : -(void)viewDidLoad or where you call -(void)reloadTable e.g.

+2
source

Your application crashes because it is trying to select a row that may not be displayed at the moment. You are trying to select a row in your data source method "cellForRowAtIndexPath" when data may not be available so far. That is why you get an error beyond boundaries.

In your specific example, you can try to select a previously selected row inside your "didSelectRowAtIndexPath" before updating the value, it will not be broken because your data is 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]; } 
+1
source
 [tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:[[[NSUserDefaults standardUserDefaults] objectForKey:kPreviousSelectedRow] integerValue] inSection:0] animated:YES scrollPosition:UITableViewScrollPositionNone]; 

Should not be inside cellForRowAtIndexpath .

Get indexPath indexPath from didSelectRowAtIndexPath , which runs every time the user selects a cell. If you want to call another method when the user deselects a cell or selects another cell, use

 -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
0
source

You can create an array with a capacity equal to the number of rows. Probably populate it with NO BOOL values ​​(actually [NSnumber numberWithBool:], since they must be objects).

Then in

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

change the value of the object at indexPath.row,

And in

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

check if the BOOL value from your array is set to YES, and then select the cell. (cell.selected = YES)

You can go the extra mile and create a custom cell with a custom selection type or something else and make a method in the cell that your selected project will apply and call this method in cellForRowAtIndexPath.

0
source

Oh, I just replace selectRowAtindex with layoutsubview, and now it won't break. thanks hint SVGreg.

0
source

SVGreg was right. You must work with the cell inside another method. But viewDidLoad is not the best option. You can try this useful delegation method.

 - (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; } 
0
source

Source: https://habr.com/ru/post/1498596/


All Articles