Bruno
Bruno

Reputation: 1032

Checkmarks single selection

I'm currently developing a UITableView with items for selection with check marks. The problem is I need to put a restriction on how many items are selected at a single time.

For Example:

NO onions, NO salt, YES milk, NO oranges.

As this example shows, I need a restriction so that the user can only select one item.

Current Code:

-(void)checkButtonPressed:(id)sender event:(id)event {
    NSSet *touches = [event allTouches];
    UITouch *touch = [touches anyObject];
    CGPoint currentTouchPosition = [touch locationInView:self.myTableView];
    indexP = [self.myTableView indexPathForRowAtPoint: currentTouchPosition];

    NSMutableDictionary *item = [[NSMutableDictionary alloc] init];
    //MasterCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"MasterCell"];
    item = [arrayData objectAtIndex:indexP.row];

    if (indexP != nil) {
        [self tableView: self.myTableView accessoryButtonTappedForRowWithIndexPath:indexP];
    }

    [self.myTableView reloadData]; 
}

- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
    NSMutableDictionary *item = [arrayData objectAtIndex:indexPath.row];

    BOOL checked = [[item objectForKey:@"checked"] boolValue];

    [item setObject:[NSNumber numberWithBool:!checked] forKey:@"checked"];

    UITableViewCell *cell = [item objectForKey:@"cell"];
    UIButton *button = (UIButton *)cell.accessoryView;

    UIImage *newImage = (checked) ? [UIImage imageNamed:@"unchecked.png"] : [UIImage imageNamed:@"checked.png"];
    [button setBackgroundImage:newImage forState:UIControlStateNormal];

    NSLog(@"accessoryButtonTappedForRowWithIndexPath____");
}

My cellForRowAtIndexPath:

- (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];
    }

    NSMutableDictionary *item = [arrayData objectAtIndex:indexPath.row];
    UILabel *nomeLabel = (UILabel *)[cell viewWithTag:2];

    UIButton *btnCheck = (UIButton *)[cell viewWithTag:3];
    BOOL checked = [[item objectForKey:@"checked"] boolValue];
    UIImage *image = (checked) ? [UIImage imageNamed:@"checked.png"] : [UIImage imageNamed:@"unchecked.png"];
    [btnCheck setBackgroundImage:image forState:UIControlStateNormal];

    nomeLabel.text = [item valueForKey:@"nome"];
    nomeLabel.textColor = [UIColor blackColor];
    [btnCheck addTarget:self action:@selector(checkButtonPressed:event:) forControlEvents:UIControlEventTouchUpInside];

    return cell;
}

Thanks in advance and sorry for my bad English, please don't down vote, just ask if you have any doubt I'm always around to answer.

Upvotes: 0

Views: 430

Answers (3)

Balu
Balu

Reputation: 8460

try like this may be it helps you, here lastIndexPath is an NSIndexPath variable declared in .h file.

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

        UITableViewCell* Cell = [tableView cellForRowAtIndexPath:indexPath]; 
        int new = [indexPath row]; 
        int old = (lastIndexPath != nil) ? [lastIndexPath row] : -1; 

        if(new != old) 
        { 
            Cell.accessoryType = UITableViewCellAccessoryCheckmark; 
            UITableViewCell* oldCell = [tableView cellForRowAtIndexPath:lastIndexPath]; 
            oldCell.accessoryType = UITableViewCellAccessoryNone;
           lastIndexPath = indexPath; 

        } 

    }   

Upvotes: 1

Manann Sseth
Manann Sseth

Reputation: 2745

Try this ::

.h File,

@property(nonatomic, retain) NSIndexPath *lastIndexPath;

.m File,

int oldRow, newRow;

Table Methods:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CustomCellIdentifier = @"customCell";
    customCell *cell = (customCell *)[tableView dequeueReusableCellWithIdentifier: CustomCellIdentifier];
    if (cell == nil)
    {
        NSArray *nib;
        nib= [[NSBundle mainBundle] loadNibNamed:@"customCell" owner:self options:nil];
        for (id oneObject in nib)
            if ([oneObject isKindOfClass:[customCell class]])
                cell = (customCell *)oneObject;

        newRow = [indexPath row];
        oldRow = [[self lastIndexPath] row];


        cell.accessibilityViewIsModal = (newRow == oldRow && lastIndexPath != nil) ? NO : YES;

        if(cell.accessibilityViewIsModal == NO)
            cell.imgCheck.image = [UIImage imageNamed:@"Checkbox_Checked_New.png"];
        else
            cell.imgCheck.image = [UIImage imageNamed:@"Checkbox_Unchecked_New.png"];

        return cell;
    }
}

DidSelect ::

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    newRow = [indexPath row];
    oldRow = [[self lastIndexPath] row];

    //Check Mark Feature
    if (newRow != oldRow)
    {
        customCell *newCell = (customCell *)[tableView cellForRowAtIndexPath:indexPath];
        newCell.imgCheck.image = [UIImage imageNamed:@"Checkbox_Checked_New.png"];

        customCell *oldCell = (customCell *)[tableView cellForRowAtIndexPath:lastIndexPath];
        oldCell.imgCheck.image = [UIImage imageNamed:@"Checkbox_Unchecked_New.png"];

        [self setLastIndexPath:indexPath];
    }
    else
    {
        customCell *newCell = (customCell *)[tableView cellForRowAtIndexPath:indexPath];
        newCell.imgCheck.image = [UIImage imageNamed:@"Checkbox_Checked_New.png"];

        [self setLastIndexPath:indexPath];
    }
}

Upvotes: 2

gaige
gaige

Reputation: 17481

Basically, for this kind of business logic, you're going to have to code it yourself. When using table views as what are basically radio buttons, the only way to enforce the requirement of single selection is to write code that handles the situation of the user trying to select the second item in the manner that your system will require:

  • Allow multiple selections (not the case here, but in some cases you might)
  • Remove all other checks that are incompatible with this, check the selected item, and tell the table view to refresh all of the rows you just changed
  • Present an error to the user in some fashion (blink, alert, sound) – almost never a good idea when you can allow direct manipulation.

Upvotes: 1

Related Questions