IOS - Skip through cells and retrieve data

Sorry, I'm pretty new to iOS dev.

I have a UITableView setting of cells pulled from a single XiB. I created an on / off switch in nib, and I'm trying to save the state of the switch on viewWillDisappear for the number of cells that I have. (More precisely, 6 cells).

How can I scroll through all cells and save this information?

I tried this in my UIViewController to get information for a single cell:

 - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; UITableView *tv = (UITableView *)self.view; UITableViewCell *tvc = [tv cellForRowAtIndexPath:0]; } 

it gives me the error "Software received signal:" EXC_BAD_INSTRUCTION ".

How can i do this?

+4
source share
2 answers

You must pass a valid NSIndexPath to cellForRowAtIndexPath: You used 0, which means no index.

You should use something like this:

 UITableViewCell *tvc = [tv cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; 

BUT . Do not do this. Do not save state in UITableViewCell.
Refresh the data source when the switch has changed its state.

If you have implemented the UITableViewDataSource methods, it is correct why your tableView reuses cells. This means that the state of your cells will disappear when the cells are reused.

Your approach can work for 6 cells. But this will not succeed for 9 cells.
It will probably even fail if you scroll the first cell from the screen.


I wrote a small demo (if you are not using ARC add release , where they are needed) to show you how you should do this:

 - (void)viewDidLoad { [super viewDidLoad]; self.dataSource = [NSMutableArray arrayWithCapacity:6]; for (NSInteger i = 0; i < 6; i++) { [self.dataSource addObject:[NSNumber numberWithBool:YES]]; } } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; UISwitch *aSwitch = [[UISwitch alloc] init]; [aSwitch addTarget:self action:@selector(switchChanged:) forControlEvents:UIControlEventValueChanged]; cell.accessoryView = aSwitch; } UISwitch *aSwitch = (UISwitch *)cell.accessoryView; aSwitch.on = [[self.dataSource objectAtIndex:indexPath.row] boolValue]; /* configure cell */ return cell; } - (IBAction)switchChanged:(UISwitch *)sender { // UITableViewCell *cell = (UITableViewCell *)[sender superview]; // NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; CGPoint senderOriginInTableView = [sender convertPoint:CGPointZero toView:self.tableView]; NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:senderOriginInTableView]; [self.dataSource replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithBool:sender.on]]; } 

since you are not very difficult not to save state in cells :-)

+11
source

Moving [super viewDidDisappear:animated]; at the end of your method may be the most appropriate way to solve the problem. If this does not work, move the logic to viewWillDisappear:animated:

The best way to handle this would be to not read the current state from the view at all. Rather, the view should convey the state of the model with each update. Thus, you can collect the current state from your model, completely regardless of the state of your view.

+1
source

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


All Articles