简体   繁体   中英

Radio button logic in UItableViewCells

Hey I'm working on a screen where user have option groups for example "Drink" which is title of section in my tableView, and their choices are "7up", "coke", etc which are cells of my table.

Now every Option Group choice (every cell in order words) has one radio button. I want to implement this. I'm facing problem if user selects any cell's radio button then other radio buttons should be deselected but how?

any help please

You should create a function to check your radio button from your custom cell and implements a delegate method to inform your TableViewController that your button on that cell was selected.

Your TableViewController needs to implements that delegate (dont forget to set each cell.delegate = self).

Then in your delegate method you create a loop to uncheck all of the radio buttons of the cells in the section except the cell you just checked.

Something like that :

This is a custom UITableViewCell with a button. The images checked and uncheck need to look like a radio button checked and uncheked Here is the .h file :

//RadioCell.h
@protocol RadioCellDelegate <NSObject>
    -(void) myRadioCellDelegateDidCheckRadioButton:(RadioCell*)checkedCell;
@end

@interface RadioCell : UITableViewCell
     -(void) unCheckRadio;
     @property (nonatomic, weak) id <RadioCellDelegate> delegate;
@end

This is the .m file of RadioCell

//RadioCell.m
@property (nonatomic, assign) UIButton myRadio;

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)reuseIdentifier
   _myRadio = [UIButton buttonWithType:UIButtonTypeCustom];
   [_myRadio setImage:[UIImage imageNamed:@"uncheck"] forState:UIControlStateNormal];
   [_myRadio setImage:[UIImage imageNamed:@"check"] UIControlStateSelected];
   [_myRadio addTarget:self action:@selector(radioTouched)orControlEvents:UIControlEventTouchUpInside];
   _myRadio.isSelected = NO;

   //don't forget to set _myRadio frame
   [self addSubview:_myRadio];
}

-(void) checkRadio {
   _myradio.isSelected = YES;
}

-(void) unCheckRadio {
   _myradio.isSelected = NO;
}

-(void) radioTouched {
     if(_myradio.isSelected == YES) {
          return;
     } 
     else {
       [self checkRadio]
       [_delegate myRadioCellDelegateDidCheckRadioButton:self];
     }
}

Now just adapt your tableview controller with RadioCell (in .m file)

//MyTableViewController.m

@interface MyTableViewController () <RadioCellDelegate>
@end

  - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
   {
      static NSString *CellIdentifier = @"RadioCell";
      RadioCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
      if (cell == nil) {
          cell = [[RadioCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
      }

      cell.textLabel = @"Coke"; //or whatever you want
      cell.delegate = self;

      return cell;
   }

-(void) myRadioCellDelegateDidCheckRadioButton:(RadioCell*)checkedCell {
     NSIndexPath *checkPath = [self.tableView indexPathForCell:checkedCell];

     for (int section = 0; section < [self.tableView numberOfSections]; section++) {
         if(section == checkPath.section) {
             for (int row = 0; row < [self.tableView numberOfRowsInSection:section]; row++) {
                   NSIndexPath* cellPath = [NSIndexPath indexPathForRow:row inSection:section];
                   RadioCell* cell = (CustomCell*)[tableView cellForRowAtIndexPath:cellPath];

                   if(checkPath.row != cellPath.row) {
                       [cell unCheckRadio];
                   }
             }
         }     
     }
}

Simple solution for a 2-option radio button UITableView (but you get the idea):

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];

    NSIndexPath *newIP;

    if (!indexPath.row)
        newIP = [NSIndexPath indexPathForRow:indexPath.row+1 inSection:0];
    else
        newIP = [NSIndexPath indexPathForRow:indexPath.row-1 inSection:0];

    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

    if (cell.accessoryType == UITableViewCellAccessoryCheckmark)
        cell.accessoryType = UITableViewCellAccessoryNone;
    else{
        cell.accessoryType = UITableViewCellAccessoryCheckmark;

        UITableViewCell *newCell = [tableView cellForRowAtIndexPath:newIP];
        newCell.accessoryType = UITableViewCellAccessoryNone;
    }
}

One solution would be to make use of the table views native selection capabilities.

In a standard UITableView it's only possible to have one row selected at a time and you can use this to your advantage. By setting "Selection" in storyboard to "None" the selection of a row will not be visible.

Now you can implement your own selection display. You can override the method -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath to update your cell when it gets selected.

And you can override the method -(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath to change the cell when it's no longer selected.

UITableViewDelegate automatically calls didSelectRowAtIndexPath on the old selection, when a new selection is made, keeping the selection unique like radio buttons.

I put together a little sample project for you to try, you can download it here .

Hopefully, I have been at least a bit helpful.

Cheers!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM