Check/Uncheck the Check Box by Tapping the Cell in Table View and How to Know Which Cell Has Checked or Unchecked

check / uncheck the check box by tapping the cell in table view and how to know which cell has checked or unchecked

In order to solve your issue, as @El Capitan mentioned, you will need to use the didSelectRowAtIndexPath method to change its states. Your codes should look something along the lines of this:

// Declare a variable which stores checked rows. UITableViewCell gets dequeued and restored as you scroll up and down, so it is best to store a reference of rows which has been checked
var rowsWhichAreChecked = [NSIndexPath]()

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell:FavCell = tableView.cellForRowAtIndexPath(indexPath) as! FavCell
// cross checking for checked rows
if(rowsWhichAreChecked.contains(indexPath) == false){
cell.checkBox.isChecked = true
rowsWhichAreChecked.append(indexPath)
}else{
cell.checkBox.isChecked = false
// remove the indexPath from rowsWhichAreCheckedArray
if let checkedItemIndex = rowsWhichAreChecked.indexOf(indexPath){
rowsWhichAreChecked.removeAtIndex(checkedItemIndex)
}
}
}

To redisplay cells which have been checked before after scrolling the rows out of view, at your cellForRowAtIndexPath, perform the same checking against rowsWhichAreChecked array and set its states accordingly.

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

let cell:FavCell = self.FavTableView.dequeueReusableCellWithIdentifier("FCell") as! FavCell
cell.FLabel1.text=arrDict[indexPath.section] .valueForKey("favourite_name") as? String
cell.FLabel2.text=arrDict[indexPath.section] .valueForKey("favourite_address") as? String

if(rowsWhichAreChecked.contains(indexPath) == false){
cell.checkBox.isChecked = true
}else{
cell.checkBox.isChecked = false
}
}
return cell
}

EDITED ANSWER

I have got your code to work but I had to make some modifications to your Checkbox class and ViewController

Checkbox.swift

class CheckBoxButton: UIButton {

// Images
let checkedImage = UIImage(named: "CheckBoxChecked")! as UIImage
let uncheckedImage = UIImage(named: "CheckBoxUnChecked")! as UIImage

// Bool property
var isChecked: Bool = false {
didSet{
if isChecked == true {
self.setImage(uncheckedImage, forState: .Normal)
} else {
self.setImage(checkedImage, forState: .Normal)
}
}
}

override func awakeFromNib() {
self.userInteractionEnabled = false
// self.addTarget(self, action: #selector(CheckBoxButton.buttonClicked(_:)), forControlEvents: UIControlEvents.TouchUpInside)
// self.isChecked = false
}

func buttonClicked(sender: UIButton) {
if sender == self {
if isChecked == true {
isChecked = false
} else {
isChecked = true
}
}
}

}

ViewController.swift

class FavVC: UIViewController, UITableViewDelegate, UITableViewDataSource {

@IBOutlet weak var FavTableView: UITableView!

var rowsWhichAreChecked = [NSIndexPath]()

//var FData = [FavouritesData]()

var arrDict :NSMutableArray=[]

let cellSpacingHeight: CGFloat = 5 // cell spacing from each cell in table view

override func viewDidLoad() {

self.FavTableView.delegate = self
self.FavTableView.dataSource = self

super.viewDidLoad()

self.jsonParsingFromURL()

let nib = UINib(nibName:"FavCell", bundle: nil)

FavTableView.registerNib(nib, forCellReuseIdentifier: "FCell")

}

// web services method
func jsonParsingFromURL ()
{
// let token = NSUserDefaults.standardUserDefaults().valueForKey("access_token") as? String

let url = NSURL(string: "some url")

let session = NSURLSession.sharedSession()

let request = NSURLRequest(URL: url!)

let dataTask = session.dataTaskWithRequest(request) { (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in
// print("done, error: \(error)")

if error == nil
{

dispatch_async(dispatch_get_main_queue())
{
self.arrDict=(try! NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)) as! NSMutableArray
if (self.arrDict.count>0)
{
self.FavTableView.reloadData()
}
}

}

}
dataTask.resume()

//
// let StringUrl = "http"+token!

// let url:NSURL = NSURL(string: StringUrl)!

// if let JSONData = NSData(contentsOfURL: url)
// {
// if let json = (try? NSJSONSerialization.JSONObjectWithData(JSONData, options: [])) as? NSDictionary
// {
// for values in json
// {
// self.FData.append()
// }

// if let reposArray = json["data"] as? [NSDictionary]
// {
//
// for item in reposArray
// {
// let itemObj = item as? Dictionary<String,AnyObject>
//
// let b_type = itemObj!["business_type"]?.valueForKey("type")
//
// //self.Resultcount.text = "\(b_type?.count) Results"
//
// if (b_type as? String == "Taxis")
// {
//
// self.FData.append(FavouritesData(json:item))
//
// }
// }
// }

// }
// }

}

func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
// return self.FData.count
return self.arrDict.count
}

// number of rows
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return 1
}

// height for each cell
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
{
return cellSpacingHeight
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{

let cell:FavCell = self.FavTableView.dequeueReusableCellWithIdentifier("FCell") as! FavCell
cell.FLabel1.text=arrDict[indexPath.section] .valueForKey("favourite_name") as? String
cell.FLabel2.text=arrDict[indexPath.section] .valueForKey("favourite_address") as? String

let isRowChecked = rowsWhichAreChecked.contains(indexPath)

if(isRowChecked == true)
{
cell.checkbox.isChecked = true
cell.checkbox.buttonClicked(cell.checkbox)
}else{
cell.checkbox.isChecked = false
cell.checkbox.buttonClicked(cell.checkbox)
}

return cell
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell:FavCell = tableView.cellForRowAtIndexPath(indexPath) as! FavCell
// cross checking for checked rows
if(rowsWhichAreChecked.contains(indexPath) == false){
cell.checkbox.isChecked = true
cell.checkbox.buttonClicked(cell.checkbox)
rowsWhichAreChecked.append(indexPath)
}else{
cell.checkbox.isChecked = false
cell.checkbox.buttonClicked(cell.checkbox)
// remove the indexPath from rowsWhichAreCheckedArray
if let checkedItemIndex = rowsWhichAreChecked.indexOf(indexPath){
rowsWhichAreChecked.removeAtIndex(checkedItemIndex)
}
}
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}

}

Check Uncheck buttons in uitableview's cell

For Check-Uncheck functionality only buttonClicked: method is not enough. You will have also put the condition in cellForRowAtIndexPath: method for which button is selected or which in unselected because cellForRowAtIndexPath: method will call each time when you will scroll your UITableView and cells will be refresh.
And i saw your previous question you're adding two buttons with two action not a good way just change the image of button for check-uncheck.

So here is what i do for this -

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController<UITableViewDelegate, UITableViewDataSource>
{
IBOutlet UITableView *tblView;
NSMutableArray *arrayCheckUnchek; // Will handle which button is selected or which is unselected
NSMutableArray *cellDataArray; // this is your data array
}

@end

Now in ViewController.m class -

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.

arrayCheckUnchek = [[NSMutableArray alloc]init];
//Assign your cell data array
cellDataArray = [[NSMutableArray alloc]initWithObjects:@"cell-1",@"cell-2",@"cell-3",@"cell-4",@"cell-5", nil];

// setting all unchecks initially
for(int i=0; i<[cellDataArray count]; i++)
{
[arrayCheckUnchek addObject:@"Uncheck"];
}

}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [cellDataArray 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 = [cellDataArray objectAtIndex:indexPath.row];

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:CGRectMake(270.0, 7.0, 30.0, 30.0)];

if([[arrayCheckUnchek objectAtIndex:indexPath.row] isEqualToString:@"Uncheck"])
[button setImage:[UIImage imageNamed:@"uncheck_icon"] forState:UIControlStateNormal];
else
[button setImage:[UIImage imageNamed:@"check_icon"] forState:UIControlStateNormal];

[button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:button];

return cell;
}

-(void)buttonClicked:(id)sender
{
//Getting the indexPath of cell of clicked button

CGPoint touchPoint = [sender convertPoint:CGPointZero toView:tblView];
NSIndexPath *indexPath = [tblView indexPathForRowAtPoint:touchPoint];

// No need to use tag sender will keep the reference of clicked button
UIButton *button = (UIButton *)sender;

//Checking the condition button is checked or unchecked.
//accordingly replace the array object and change the button image
if([[arrayCheckUnchek objectAtIndex:indexPath.row] isEqualToString:@"Uncheck"])
{
[button setImage:[UIImage imageNamed:@"check_icon"] forState:UIControlStateNormal];
[arrayCheckUnchek replaceObjectAtIndex:indexPath.row withObject:@"Check"];
}
else
{
[button setImage:[UIImage imageNamed:@"uncheck_icon"] forState:UIControlStateNormal];
[arrayCheckUnchek replaceObjectAtIndex:indexPath.row withObject:@"Uncheck"];
}
}

And finally it will look like -

Sample Image

check and uncheck buttons in table view controller

In daysRemainderTableView take imageview with name daysSelectionimageView.This is example to select and deselect rows in tableviewcell .

     @IBOutlet weak var daysRemainderTableView: UITableView!

var days = ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"]

var selectedDaysArray = [Int]()

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return days.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "RemainderDaysCell", for: indexPath)as! RemainderDaysCell
cell.remainderDaysLabel.text = "\(days[indexPath.row])"

if selectedDaysArray.contains(indexPath.row){
cell.daysSelectionimageView.image = #imageLiteral(resourceName: "selectedImage")
}else{
cell.daysSelectionimageView.image = #imageLiteral(resourceName: "ring")
}
return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) as? RemainderDaysCell
{
if selectedDaysArray.isEmpty{
self.selectedDaysArray = [Int]()
}
if selectedDaysArray.contains(indexPath.row){
if let indexElement = selectedDaysArray.index(of: indexPath.row){
cell.daysSelectionimageView.image = #imageLiteral(resourceName: "ring")
selectedDaysArray.remove(at: indexElement)
}
}else{
cell.daysSelectionimageView.image = #imageLiteral(resourceName: "selectedImage")
selectedDaysArray.append(indexPath.row)
}
}
}

I am checking selectedDaysArray in cellforrow at indexpath and didSelectRow ai indexpath ,if selectedDaysArray has selected index i am removing element if it is not i am appending indexemement to selectedDaysArray.

Check and uncheck the same UITableViewCell

Where your datasource is load
do this

arrSelected = [[NSMutableArray alloc] init];
for (int i = 0; i <arrSong.count; i++) {
[arrSelected addObject:[NSNumber numberWithBool:NO]];
}

In your cell for indexpath do this

if ([[arrSelected objectAtIndex:indexPath.row] boolValue] == YES) {
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
}
else{
[cell setAccessoryType:UITableViewCellAccessoryNone];
}

To select/deselect do thisin you tableview:didselect

    if ([[arrSelected objectAtIndex:indexPath.row] boolValue] == YES) {
[arrSelected replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithBool:NO]];
}
else{
[arrSelected replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithBool:YES]];
}

TableView CheckMark and Uncheck With Scroll Up Still Checked Cell Value In Ios Swift 4

I think if someone were to run your code it would not show any error. But with real data it probably will. The reason is the way you store your checkmarks. You store the data of a row into the temp array when you should be storing the actualy indexPath of the array so that only that row gets the checkmark. In your case, if a row has 1 inside it's label and you click on it, that cell will be highlighted. Now if you start scrolling and another cell contains 1 then that row will also be highlighted.

I have modified your example for the case of a single section. If there is more than one section, you need to store the indexPath instead of indexPath.row.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "id")
cell = UITableViewCell.init(style: .default, reuseIdentifier: "id")
cell?.textLabel?.text = String(numarr[indexPath.row])
if temp.contains(indexPath.row) {
cell?.accessoryType = .checkmark
} else {
cell?.accessoryType = .none
}
return cell!
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

let cell = tableView.cellForRow(at: indexPath)
if temp.contains(indexPath.row) {
cell?.accessoryType = .none
temp.remove(at: indexPath.row)
} else {
cell?.accessoryType = .checkmark
temp.append(indexPath.row)
}
}

UITableViewCell Accessory Type Checked on Tap & Set other unchecked

I would keep track of the data that should be checked and change the cell in tableView:didSelectRowAtIndexPath: and update which data is checked in tableView:cellForRowAtIndexPath: like this:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// do usual stuff here including getting the cell

// determine the data from the IndexPath.row

if (data == self.checkedData)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}

return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// determine the selected data from the IndexPath.row

if (data != self.checkedData) {
self.checkedData = data;
}

[tableView reloadData];
}

Uncheck UITableview custom checkbox option in Swift

Instead of let cell = tableView.dequeueReusableCellWithIdentifier... I would use

let cell = tableView.cellForRowAtIndexPath(indexPath) as! CustomCellVC

This way you get a reference to the cell you want to change the image in. tableView.dequeueReusableCellWithIdentifier is meant to be used in delegate method tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) when you want to recycle your cells for better performance.

Also cell.ivRiskCellImage.image!.isEqual(UIImage(named: "UncheckedBox")) doesn't work, because UIImage(named: "UncheckedBox") creates a new UIImage, which isn't the same as the UIImage you want to check it against.



Related Topics



Leave a reply



Submit