Reputation: 1188
I'm working on a project coded in swift 3 and I have a UIButton inside a UITableViewCell where the image changes once the button is tapped. Though the selected buttons get selected as intended, once the UITableview scrolls the selected images gets disappear since the cells are been reused. As I'm new to programming having troubles of writing the logic. Help would much appreciate the code as bellow.
CellFoRow
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
//Button_Action
addSongButtonIdentifier(cell: cell, indexPath.row)
}
This is where the cell is been created.
func addSongButtonIdentifier(cell: UITableViewCell, _ index: Int) {
let addButton = cell.viewWithTag(TABLE_CELL_TAGS.addButton) as! UIButton
//accessibilityIdentifier is used to identify a particular element which takes an input parameter of a string
//assigning the indexpath button
addButton.accessibilityIdentifier = String (index)
// print("visible Index:",index)
print("Index when scrolling :",addButton.accessibilityIdentifier!)
addButton.setImage(UIImage(named: "correct"), for: UIControlState.selected)
addButton.setImage(UIImage(named: "add_btn"), for: UIControlState.normal)
addButton.isSelected = false
addButton.addTarget(self, action: #selector(AddToPlaylistViewController.tapFunction), for:.touchUpInside)
}
the tap function
func tapFunction(sender: UIButton) {
print("IndexOfRow :",sender.accessibilityIdentifier!)
// if let seporated by a comma defines, if let inside a if let. So if the first fails it wont come to second if let
if let rowIndexString = sender.accessibilityIdentifier, let rowIndex = Int(rowIndexString) {
self.sateOfNewSongArray[rowIndex] = !self.sateOfNewSongArray[rowIndex]//toggle the state when tapped multiple times
}
sender.isSelected = !sender.isSelected //image toggle
print(" Array Data: ", self.sateOfNewSongArray)
selectedSongList.removeAll()
for (index, element) in self.sateOfNewSongArray.enumerated() {
if element{
print("true:", index)
selectedSongList.append(songDetailsArray[index])
print("selectedSongList :",selectedSongList)
}
}
}
Upvotes: 0
Views: 1289
Reputation: 24341
You need to maintain the button selection status at the controller level. You need to make changes to the model that you are using to configure your tableview.
I have created a similar scenario. I have used an array selectionStatusArray
to maintain the button's selection status.
Example:
1. UIViewController
containing UITableView
class ViewController: UIViewController, UITableViewDataSource
{
@IBOutlet weak var tableView: UITableView!
var selectionStatusArray = [false, false, false, false, false] //Array that maintains the button selection status
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return selectionStatusArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TableViewCell
addSongButtonIdentifier(cell: cell, indexPath.row)
return cell
}
func addSongButtonIdentifier(cell: TableViewCell, _ index: Int)
{
cell.addButton.tag = index
cell.addButton.isSelected = selectionStatusArray[index]
cell.tapHandler = {
self.selectionStatusArray[$0] = cell.addButton.isSelected
}
}
}
2. Custom UITableViewCell
class TableViewCell: UITableViewCell
{
@IBOutlet weak var addButton: UIButton!
var tapHandler: ((Int)->())?
@IBAction func tapFunction(_ sender: UIButton)
{
sender.isSelected = !sender.isSelected
tapHandler?(sender.tag)
}
}
You can configure the UITableViewCell
according to your requirements.
Upvotes: 1
Reputation: 1361
You have this code addButton.isSelected = false
which is causing the problem because I believe you are calling the function addSongButtonIdentifier
inside tableView delegate
method, you should not set all those property inside tableView delegate
.
Instead you should do it initially and only once for each of your cell like either in storyboard itself or by providing a model to cell class.
Upvotes: 0