Swift: Change the Cell's Uibutton Image with Tableview Didselect Method

Swift: Change the cell's UIButton Image With tableView DidSelect method

Check This

Sample Image

import UIKit

class ButtonTblViewController: UIViewController,UITableViewDelegate, UITableViewDataSource {

var arry = ["Montitanki Chowk","Greenland Chokdi"]
var SelectData = [NSMutableDictionary]()

@IBOutlet weak var tbleVw: UITableView!

override func viewDidLoad() {
super.viewDidLoad()

for i in 0..<arry.count
{
self.SelectData.append(["data":arry[i],"isSelect":"NO"])
}

self.tbleVw.reloadData()
// Do any additional setup after loading the view.
}

// MARK - tableView Delegates

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return SelectData.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:listTble = tableView.dequeueReusableCell(withIdentifier: "CellID", for: indexPath as IndexPath) as! listTble
cell.lblTit.text = self.SelectData[indexPath.row].value(forKey: "data") as? String

cell.btnRdo.tag = indexPath.row
let tapgesture = UITapGestureRecognizer(target: self , action: #selector(self.sectionTapped(_:)))
cell.btnRdo.addGestureRecognizer(tapgesture)

let selData = self.SelectData[indexPath.row].value(forKey: "isSelect") as! NSString

if selData == "NO" {
cell.btnRdo.setImage( UIImage(named: "btnUnSel"), for: .normal)
} else {
cell.btnRdo.setImage( UIImage(named: "btnSel"), for: .normal)
}

return cell
}

@objc func sectionTapped(_ sender: UITapGestureRecognizer){
if(self.SelectData[(sender.view?.tag)!].value(forKey: "isSelect") as! String == "NO"){
self.SelectData[(sender.view?.tag)!].setValue("YES", forKey: "isSelect")
}else{
self.SelectData[(sender.view?.tag)!].setValue("NO", forKey: "isSelect")
}
self.tbleVw.reloadData()
}

/*
// MARK: - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/

}

class listTble: UITableViewCell {
@IBOutlet weak var lblTit: UILabel!
@IBOutlet weak var btnRdo: UIButton!
}

Out Put

Sample Image

Change rows button image source on click?

Try this out:

Step 1 : In didSelectRowAtIndexPath update the model that drives cell image:

self.cellTickedImage = UIImage(named: "tick.png”)

Step 2 : In didSelectRowAtIndexPath reload the cell to see the change:

self.tableView.beginUpdates()
self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
self.tableView.endUpdates()

Step 3 : In didDeselectRowAtIndexPath update the model that drives cell image:

self.cellTickedImage = UIImage(named: "unTicked.png”)

Step 4 : In didDeselectRowAtIndexPath reload the cell to see the change:

self.tableView.beginUpdates()
self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
self.tableView.endUpdates()

Step 5 : In cellForRowAtIndexPath set the cell image correctly:

cell.tickBtn.setImage(self.cellTickedImage, forState: UIControlState.Normal)
cell.tickBtn.setImage(self.cellTickedImage, forState: UIControlState.Highlighted)

EDIT: Post discussion with OP on chat - Few assumptions from discussion

  1. No two cells shall have same text on it.
  2. On one tap show one image and on second tap show second image.

Considering this, here is the high level algorithm for the fix:

  1. Create a global dictionary checkListDict with key as cell text and value as image status flag. Initially set value is 0 for all cell text. Considering 1 as tick.png and 0 as unTicked.png.
  2. In didSelectRowAtIndexPath update the flag like this:

->

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
//change tickBtn's image src to tick.png
let cell = tableView.cellForRowAtIndexPath(indexPath) as? CheckListCell
let selectedCellText = (cell!.taskLbl?.text)!

if checkListDict[selectedCellText] == 0 {
checkListDict[selectedCellText] = 1
}
else{
checkListDict[selectedCellText] = 0
}

self.checkListTableView.beginUpdates()
self.checkListTableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
self.checkListTableView.endUpdates()
}

  1. Finally, use the updated model in cellForRowAtIndexPath like this:

->

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = checkListTableView.dequeueReusableCellWithIdentifier("CheckListCell", forIndexPath: indexPath) as! CheckListCell

let selectedCellText = checkListData[indexPath.section][indexPath.row]

cell.taskLbl?.text = selectedCellText
let cellImage = checkListDict[selectedCellText] == 0 ? UIImage(named: "unTicked.png") : UIImage(named:"tick.png")


cell.tickBtn.setImage(cellImage, forState: UIControlState.Normal)
cell.tickBtn.setImage(cellImage, forState: UIControlState.Highlighted)

return cell
}

Swift: Change button image in table view on click

When working with tables and collection views, all the objects you have in a custom cell can be easily accessed in cellForRowAtIndexPath (for UITables)

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("ActionCell", forIndexPath: indexPath) as ActionCell

var action = actions[indexPath.row] as Action

cell.nameLabel?.text = action.name
cell.listLabel?.text = action.list
cell.dateLabel?.text = action.date
cell.checkboxButton = action.isChecked
cell.checkBoxButton.setImage(UIImage(named:"checkedImage"), forState:UIControlState.Normal)
return cell
}

more over I would suggest to change constants to variables. I'm new to Swift too and "let" declares a static variable.

I find very cool the use of the conditional operator (?:) in these cases:

cell.checkBoxButton.setImage(UIImage(named:(any_boolean_condition ? "checkedImage" : "uncheckedImage")), forState:UIControlState.Normal)

so it can return one image name for the condition True and another name for the condition False.

UITableView when click button and change its image Swift 4

When you perform dequeueReusableCell, iOS not generates your array's counts of cells. Instead of this, it generates fewer cells and use these cells again and again on scrolls. In your case selected shown cells are actually same cells.

The solution: You should store the selection flag for your cells in your datasource array (in your case its services). And in cellForRowAt method you should select or deselect checkboxes according to your stored selection data.

Edit:

if  services[indexPath.row].choose == "0" {
cell.check.setImage(UIImage(named: "Rectangle1"), for: .normal)
services[indexPath.row].choose = "1"
chooseservicesw.updateValue("0", forKey: String(indexPath.row+1))
} else if services[indexPath.row].choose == "1" {
cell.check.setImage(UIImage(named: "checkbox1"), for: .normal)
services[indexPath.row].choose = "0"
chooseservicesw.removeValue(forKey: String(indexPath.row+1))
}

Add this part to end of your cellForRowAt method.

Swift - Clicked button inside tableview cell does not call the did select row at function of that cell

Button action won't call the didSelectRowAt. You should go for delegate method. If not aware about delegate means refer this

Unable to change the image of UItableviewcell Button

Change your code in didSelectRowAtIndexPath as

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

let cell : categoryCell = tableView.cellForRowAtIndexPath(indexPath) as! categoryCell

cell.category_button.setImage(UIImage(named: "check_checkbox"), forState: UIControlState.Normal)
let dic : NSDictionary = categoryitem.objectAtIndex(indexPath.row) as! NSDictionary
print(dic.valueForKey("category_id") as! String)
}

Mistake you did

let cell : categoryCell = tableView.dequeueReusableCellWithIdentifier("categoryCell") as! categoryCell

will return you the cell for reuse but you need to access the currently loaded cell at indexPath where user tapped :) So use cellForRowAtIndexPath.
cellForRowAtIndexPath returns the currently loaded cell at indexPath



Related Topics



Leave a reply



Submit