Swift: Change the cell's UIButton Image With tableView DidSelect method
Check This
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
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
- No two cells shall have same text on it.
- On one tap show one image and on second tap show second image.
Considering this, here is the high level algorithm for the fix:
- 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 astick.png
and 0 asunTicked.png
. - 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()
}
- 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
How to Load an Image from Documents Directory on MACos Swift
Swift 2.1 [Uint8] --Utf8--> String
Fixing Nsurlconnection Deprecation from Swift 1.2 to 2.0
How to Display Data from Firebase Faster
Lesser Than or Greater Than in Swift Switch Statement
@Noescape Attribute in Swift 1.2
How to Create Swift Class for Category
How to Make Class Methods/Properties in Swift
Why Use Required Initializers in Swift Classes
Find Difference in Seconds Between Nsdates as Integer Using Swift
What's the Difference Between Struct Based and Class Based Singletons
Swift 2/iOS 9 - Libz.Dylib Not Found
Convert a Swift Array of String to a to a C String Array Pointer
Uiwebview Dynamic Content Size