спасибо спасибо - 2 months ago 18
iOS Question

Call something based on UITableView rows selected, in an IBAction

I just saw a post about selecting multiple UITableView rows and based on which row/rows are selected, something will happen when you press a button linked to an IBAction.

It's an interesting question and I've played around with it, but now I'm stuck a bit.

As you can see I have a NSMutableArray called selectedIndexes, and the selected row/rows are shown in the console using a NSLog. This works fine:

- (IBAction)doSomethingWithSelectedRows:(id)sender {

for (NSNumber *data in self.selectedIndexes) {
NSLog(@"Row %ld is selected.", (long)[data integerValue] +1);
}

if (WHAT SHOULD BE PUT HERE?) {
}
//Do whatever you want here.
}


The question is, what should be put in that if statement above if you want this to happen:

if (row 2 and row 1 are selected {

//Run this code.

}


UPDATE:

Here's more code:

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

UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];

if ([selectedCell accessoryType] == UITableViewCellAccessoryNone) {

[selectedCell setAccessoryType:UITableViewCellAccessoryCheckmark];
[_selectedIndexes addObject:[NSNumber numberWithInteger:indexPath.row]];

} else {

[selectedCell setAccessoryType:UITableViewCellAccessoryNone];
[_selectedIndexes removeObject:[NSNumber numberWithInteger:indexPath.row]];

}

[tableView deselectRowAtIndexPath:indexPath animated:YES];

}

- (IBAction)doSomethingWithRowsSelected:(id)sender {

for (NSNumber *data in self.selectedIndexes) {
NSLog(@"Row %ld is selected.", (long)[data integerValue] +1);

}

}

Answer

While you can use an array, as you do, an NSMutableIndexSet is a much better data structure for this task. It allows you to check whether a given index is in the set without having to iterate through all of the objects.

@property (strong,nonatomic) NSMutableIndexSet *selectedRows;

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSUInteger row = indexPath.row;
    UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];

    if ([self.selectedRows containsIndex:row]) {
        [self.selectedRows removeIndex:row];
        [selectedCell setAccessoryType:UITableViewCellAccessoryNone];
    } else {
        [self.selectedRows addIndex:indexPath.row];
        [selectedCell setAccessoryType:UITableViewCellAccessoryCheckmark];      
    }
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
}

Now you can easily check if any two rows are selected:

- (IBAction)doSomethingWithRowsSelected:(id)sender {
    if ([self.selectedRows containsIndex:1] && [self.selectedRows containsIndex:2]) {
        // Do whatever
    }
}

Also, don't forget to set the accessory type in cellForRowAtIndexPath based on [self.selectedRows containsIndex:indexPath.row] otherwise your checkmarks will be wrong when you scroll.