Swift Tableview Cell Radio Button Implementation

Select deselect the radio in uitableview section with array in ios swift

You can use UIButton instead of SSRadioButton, and then you can change the image of button for checked and unchecked radio button.

Swift3.2:
CustomiseTableViewCell

import UIKit

protocol CustomTableViewCellDelegate {
func didToggleRadioButton(_ indexPath: IndexPath)
}

class CustomiseTableViewCell: UITableViewCell {

@IBOutlet weak var itemLabel: UILabel!
@IBOutlet weak var radioButton: UIButton!
var delegate: CustomTableViewCellDelegate?

func initCellItem() {

let deselectedImage = UIImage(named: "ic_radio_button_unchecked_white")?.withRenderingMode(.alwaysTemplate)
let selectedImage = UIImage(named: "ic_radio_button_checked_white")?.withRenderingMode(.alwaysTemplate)
radioButton.setImage(deselectedImage, for: .normal)
radioButton.setImage(selectedImage, for: .selected)
radioButton.addTarget(self, action: #selector(self.radioButtonTapped), for: .touchUpInside)
}

func radioButtonTapped(_ radioButton: UIButton) {
print("radio button tapped")
let isSelected = !self.radioButton.isSelected
self.radioButton.isSelected = isSelected
if isSelected {
deselectOtherButton()
}
let tableView = self.superview as! UITableView
let tappedCellIndexPath = tableView.indexPath(for: self)!
delegate?.didToggleRadioButton(tappedCellIndexPath)
}

func deselectOtherButton() {
let tableView = self.superview?.superview as! UITableView
let tappedCellIndexPath = tableView.indexPath(for: self)!
let indexPaths = tableView.indexPathsForVisibleRows
for indexPath in indexPaths! {
if indexPath.row != tappedCellIndexPath.row && indexPath.section == tappedCellIndexPath.section {
let cell = tableView.cellForRow(at: IndexPath(row: indexPath.row, section: indexPath.section)) as! CustomiseTableViewCell
cell.radioButton.isSelected = false
}
}
}

}

Call initCellItem method from UITableViewDataSource's delegate method:

// Your ViewController

let menuList = [ ["Cheese", "Bacon", "Egg"],
["Fanta", "Lift", "Coke"] ] // Inside your ViewController
var selectedElement = [Int : String]()

func didToggleRadioButton(_ indexPath: IndexPath) {
let section = indexPath.section
let data = menuList[section][indexPath.row]
if let previousItem = selectedElement[section] {
if previousItem == data {
selectedElement.removeValue(forKey: section)
return
}
}
selectedElement.updateValue(data, forKey: section)
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell:CustomiseTableViewCell =
tableView.dequeueReusableCell(withIdentifier: "Customise") as! CustomiseTableViewCell
let item = menuList[indexPath.section][indexPath.row]
cell.itemLabel.text = item
if item == selectedElement[indexPath.section] {
cell.radioButton.isSelected = true
} else {
cell.radioButton.isSelected = false
}
cell.initCellItem()
cell.delegate = self
// Your logic....
return cell
}

Sample Image

Add a Radio Button To UITableViewCell By Animating: iOS

You can try this I created Simple Demo.

ViewController.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController<UITableViewDelegate,UITableViewDataSource>
{
NSMutableArray *dataArray;
}

@property (weak, nonatomic) IBOutlet UITableView *mTableView;
// You can toggle the Selection by Means you can show hide the checkboxes
- (IBAction)didTapBringCheckBoxBtn:(id)sender;

@end

View controller.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];

dataArray=[[NSMutableArray alloc]init];
[dataArray addObject:@"Apple"];
[dataArray addObject:@"Mango"];
[dataArray addObject:@"Papaya"];
[dataArray addObject:@"Guava"];
[dataArray addObject:@"Pineapple"];
[dataArray addObject:@"Strawberry"];
[dataArray addObject:@"Banana"];
[dataArray addObject:@"Grapes"];
[dataArray addObject:@"Pomegranate"];
[dataArray addObject:@"Green Tea"];
[dataArray addObject:@"Raisin"];

self.mTableView.delegate=(id)self;
self.mTableView.dataSource=(id)self;
}

- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

#pragma mark - Check Box Button Action

- (IBAction)didTapBringCheckBoxBtn:(id)sender {

if(self.mTableView.editing==YES)
{
[self.mTableView setEditing:NO animated:YES];
}else{
[self.mTableView setEditing:YES animated:YES];
}

}

#pragma mark - UITableView DataSource Methods

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [dataArray count];
}

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

cell.textLabel.text = [dataArray objectAtIndex:indexPath.row];
return cell;
}

#pragma mark - UITableView Delegate Methods

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 3;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"user selected %@",[dataArray objectAtIndex:indexPath.row]);
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"user de-selected %@",[dataArray objectAtIndex:indexPath.row]);
}

@end

OutPut Will look Like This :

At Start Not showing Checkboxes :

Sample Image
On click Show CheckBox :
Sample Image

Radio button logic in UItableViewCells

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

How to hide sections in a table view using a radio button?

Take one flag (Bool I mean), It's initial value will be false. now on radio button's selection set it's value to true.

Now, change numberofSection method. It will conditionally returns 1 or 4. I mean if your flag was true then return 4 else 1! that's it!

how to implement one radio button to be active while selecting it?

  var checkIsRadioSelect = [Int]()
var webserviceArray = [modelObj]()
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let obj = webserviceArray[indexPath.row]
cell.radioButton.tag = indexPath.row
let checkIndex = self.checkIsRadioSelect.index(of: obj.wateverUniqeId)
if(checkIndex != nil){
cell.radioButton.isSelected = true

}else{
cell.radioButton.isSelected = false
}
}

@IBAction func selectRadioButton(_ sender: UIButton) {
let obj = webserviceArray[sender.tag]
let chekIndex = self.checkIsRadioSelect.index(of:obj.wateverUniqeId)
if sender.isSelected {
self.checkIsRadioSelect.remove(at: sender.tag)
} else{
if(chekIndex == nil){

self.checkIsRadioSelect.append(obj.wateverUniqeId)

}

} self.tableview.reloadData()
}

Approaches to implement tapped inserting table cell with radio buttons

For the first problem, what I would do is pre-layout that cell containing the two radio buttons either in the storyboard (You can also do it in a .xib file). Then I will set an identifier for it like "LanguageSkillSelectionTableViewCell" or something. After that, when I am about to load the new set of data into the table view I can manage the presentation of cells in the table view through the callback cellForRowAtIndexPath:

An example would be if I want to load that LanguageSkillSelectionTableViewCell always at the beginning, then I would just set it at indexPath.row == 0. else set the contents of the data list to other rows.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *tableCell;

if(_loadedNewData)
{
if(indexPath.row < dataList.count && indexPath.row > 0)
{
tableCell = (DataTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"DataTableViewCell"];

//set attributes of the tableCell
}

else
{
tableCell = (LanguageSkillSelectionTablViewCell *)[tableView dequeueReusableCellWithIdentifier:@"LanguageSkillSelectionTableViewCell"];

//set attributes of the tableCell
}
}

else
{
//load in default order
}

return tableCell;
}

You can just play with the arrangement and presentation of the cells under this callback.

For the second problem, you have to store a flag or state for that selection picked by the user in a global variable within the class. Then everytime the cells are reloaded you can just update the selection state of that cell by setting a method for that cell that would update the selection state of the radio button.

For example:

If user selected English, then it would be like:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *tableCell;

if(_loadedNewData)
{
if(indexPath.row < dataList.count && indexPath.row > 0)
{
tableCell = (DataTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"DataTableViewCell"];

//set attributes of the tableCell
}

else
{
tableCell = (LanguageSkillSelectionTablViewCell *)[tableView dequeueReusableCellWithIdentifier:@"LanguageSkillSelectionTableViewCell"];

//set attributes of the tableCell

[(LanguageSkillSelectionTablViewCell *)tableCell setLanguageSelectionState:canReadWrite];
}
}

else
{
//load in default order
}

return tableCell;
}


Related Topics



Leave a reply



Submit