I have a tableview that contains a button in the left of cell. the run works well and when i select a button a made it change its image background. The problem is when I select a buttonButtonOne selection , it select other buttons when I scroll tableview down, Other buttons selected my code is this way:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableview.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! PlayerCell
cell.BtnAdd.tag = indexPath.row
cell.BtnAdd.addTarget(self, action: #selector(CreateTeamTwo.PlayerAdded(_:)), forControlEvents: .TouchUpInside)
return cell
}
func PlayerAdded(sender: UIButton){
// let buttonTag = sender.tag
sender.setImage(UIImage(named: "btn_buy_minus.png"), forState: UIControlState.Normal)
}
can you help me please ?
Take one Array to store selected indexPaths Buttons tags. and in selector methods store all the sender tags and reload the tableView. and in cellForRow method check if current indexpath is contain in selected array then show minus image otherwise show plus image.
var selected = [Int]()
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableview.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! PlayerCell
cell.BtnAdd.tag = indexPath.row
cell.BtnAdd.addTarget(self, action: #selector(CreateTeamTwo.PlayerAdded(_:)), forControlEvents: .TouchUpInside)
if selected.contains(indexPath.row) {
cell.btn.setImage(UIImage(named: "btn_buy_minus.png"), forState: .Normal)
} else {
// here set the plus image
cell.btn.setImage(UIImage(named: "btn_buy_plus.png"), forState: .Normal)
}
return cell
}
func PlayerAdded(sender: UIButton){
selected.append(sender.tag)
self.tableView.reloadData()
}
Related
I want to change cell image when music is playing , I am using didselectrow for this when i select row it change image and when i scroll i see many other cell image is also changed i don't why please guide me
here is my code
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as? NaatListTableViewCell
cell?.btnPlayPause.setImage(UIImage(named: "pause"), for: .normal)
}
try:
var isPlayingIndex = -1
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as? NaatListTableViewCell
if indexPath.row == isPlayingIndex {
cell?.btnPlayPause.setImage(UIImage(named: "play"), for: .normal)
}else {
cell?.btnPlayPause.setImage(UIImage(named: "pause"), for: .normal)
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as? NaatListTableViewCell
if indexPath.row == isPlayingIndex {
cell?.btnPlayPause.setImage(UIImage(named: "pause"), for: .normal)
isPlayingIndex = -1
} else {
// stop current player
//
isPlayingIndex = indexPath.row
cell?.btnPlayPause.setImage(UIImage(named: "play"), for: .normal)
}
}
Instead of changing the image in didSelectRowAt method, you can do it another way by implementing setSelected(_:animated:) method in your custom UITableViewCell and handle the image status there, i.e.
override func setSelected(_ selected: Bool, animated: Bool) {
if selected {
btnPlayPause.setImage(UIImage(named: "pause"), for: .normal)
} else {
btnPlayPause.setImage(UIImage(named: "play"), for: .normal)
}
}
The above method handles the selection and de-selection for all the cells in the tableView in single-selection and multi-selection modes.
After this, you'll not need to write anything in tableView(_:didSelectRowAt:) method.
You need to maintain state for your cell manually. You might have some other data associated with your cell, from what you have asked it seems like a list of music files, you could associate with each music a unique id in its model. Now create a map of type var isPlaying = [Int: Bool]() (assuming you are going with int ids)
Then in didSelectRowAt set the value with corresponding id
self.isPlaying[YOUR_ID] = cell.isSelected
Now in your cellForRowAt method
var imageName = self.isPlaying[YOUR_ID] ? "play" : "pause"
cell?.btnPlayPause.setImage(UIImage(named: imageName), for: .normal)
I want to delete specific row when i tap a button in that cell. but here rows are deleting on the index base. if i tap button in fifth row button but 0th index row is deleting.
please help me.
here is my code:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! EmployeeTableViewCell
//cell.empImage.image = UIImage(named: countryArray[indexPath.row])
cell.empName.text = namesArray[indexPath.row]
cell.cellExpendButton.tag = indexPath.row
cell.cellExpendButton.addTarget(self, action: #selector(expandcollapseButtonClicked), for: .touchUpInside)
cell.removeRowButton.addTarget(self, action: #selector(removerowButtonClicked), for: .touchUpInside)
return cell
}
#objc func removerowButtonClicked(sender : UIButton!) {
namesArray.remove(at: sender.tag)
self.tableView.reloadData()
}
I want to remove cell in which button i tapped.
Set removeRowButton.tag by indexPath.row, now you are setting cell.cellExpendButton.tag = indexPath.row, by default tag of any component is 0
cell.removeRowButton.tag = indexPath.row
I am very confused on the reuse of the cells.
I have a table, each cell is a cell with a switch on it. If I toggle a switch I set the background color of that cell to a different color. However every time I scroll these changes don't persist.
I am subclassing UITalbeViewCell to create my own custom cell. Each cell has a different identifier. However when I scroll through the table, whatever changes I made to the cell still doesn't save. I've read similar questions but none of them worked.. Some suggested subclass which I did, some suggested use different identifier which I also did...
Here is the code of my tableview.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let key = Array(dataSource[indexPath.section].keys)[indexPath.row]
let cell = CellWithSwitch.init(style: .subtitle, reuseIdentifier: key)
cell.awakeFromNib()
let val = Array(dataSource[indexPath.section].values)[indexPath.row]
cell.switchView?.addTarget(self, action: #selector(self.switchChanged(_:)), for: .valueChanged)
if let index = key.firstIndex(of: "."){
cell.textLabel?.text = String(key.suffix(from: key.index(index, offsetBy: 1)))
}else{
cell.textLabel?.text = key;
}
cell.switchView?.setOn(val, animated: true)
return cell
}
You can change array value in switchChange action
lets i take array for switch as below:
var arrSwitch = [false,false,false,false,false,false,false,false,false,false]
Below is my cellForRowAt Method
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "customCell") as! customCell
cell. switchView.setOn(self.arrSwitch[indexPath.row], animated: false)
cell. switchView.tag = indexPath.row
cell. switchView.addTarget(self, action: #selector(self.onSwitchTap(_:)), for: .valueChanged)
return cell
}
Here is my onSwitchTap Action
#IBAction func onSwitchTap(_ sender: UISwitch) {
self.arrSwitch[sender.tag] = !self.arrSwitch[sender.tag]
}
Now on scroll it will persist last changes you have done.
I am using Swift 4 and I finally got my TableView cell working correctly . I have a like button and when a user clicks it I update only the cell that was clicked and show a new image either like or unliked, in addition I show a LikeCounter +1 for like and -1 for unlike .That's all working.
My question is how can I make it so that I only update those 2 elements on button clicked ?
right now it updates the Table View Cell . This is my code
#IBAction func voteAction(_ sender: UIButton)
{
if let indexPathm = TableView.indexPathForView(sender) {
if streamsModel.VoteStatus[sender.tag] == "0" {
streamsModel.VoteStatus[sender.tag] = "1"
streamsModel.Votes[sender.tag] = streamsModel.Votes[sender.tag] + 1
} else {
streamsModel.VoteStatus[sender.tag] = "0"
streamsModel.Votes[sender.tag] = streamsModel.Votes[sender.tag] - 1
}
TableView.reloadRows(at: [indexPathm],with: .none)
}
}
Once you click that button then it goes here
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "HomeTVC", for: indexPath) as! HomeTVC
cell.vote_status = streamsModel.VoteStatus[indexPath.row]
if streamsModel.VoteStatus[indexPath.row] != "0" {
cell.voteImage.setImage(UIImage(named: "liked"), for: .normal)
} else {
cell.voteImage.setImage(UIImage(named: "unliked"), for: .normal) }
}
I have a lot more cell elements in that TableViewCell however I would only like to update and isolate that specific piece of code in my TableViewCell .
I have tried doing it using this method Update label in custom UITableView Cell however I find that if I scroll down and then back up it reverts whatever changes I did .
// This works however if you scroll down then back up
// it reverts back to the original status
let button = sender as! UIButton
let view = button.superview!
let cell = view.superview as! HomeTVC
let indexPath = tableView.indexPathForCell(cell)
println(indexPath)
if(indexPath != nil){
if streamsModel.VoteStatus[indexPath.row] != "0" {
cell.voteImage.setImage(UIImage(named: "liked"), for: .normal)
} else {
cell.voteImage.setImage(UIImage(named: "unliked"), for: .normal) }
}
}
So now I'm calling but it's updating the whole cell .
TableView.reloadRows(at: [indexPathm],with: .none)
You can retrieve the cell and update only the properties of the cell directly like this:
if let cell = tableView.cellForRow(at: indexPath) as? HomeTVC {
// Update the cell
}
EDIT:
I missed the second part of the question, sorry. I think that the problem here is that you're not updating your model, so when you scroll up the delegate calls tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) and sets the value as saved previously on the model. You have to update the value of streamsModel.VoteStatus when the button is pressed.
I have the button working correctly, I just can't figure out how to disable it on tap. I'm not sure if I can reference it from the addSomething(sender: UIButton) function like I reference the sender.tag.
Any idea? Thanks for any help.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let myCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! ExploreCell
// Configure the cell...
myCell.configureCell(teams[indexPath.row])
myCell.addSomethingButton.tag = indexPath.row
myCell.addSomethingButton.addTarget(self, action: #selector(self.addSomething), forControlEvents: .TouchUpInside)
myCell.addSomethingButton.enabled = true
//disable cell clicking
myCell.selectionStyle = UITableViewCellSelectionStyle.None
return myCell
}
What do you need to do is to store all tapped buttons in an array to check whether the button of this tag (current indexPath.row) has been tapped:
class ViewController: UIViewController {
var tappedButtonsTags = [Int]()
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let myCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! ExploreCell
// Configure the cell...
myCell.configureCell(teams[indexPath.row])
myCell.addSomethingButton.tag = indexPath.row
// here is the check:
if tappedButtonsTags.contains(indexPath.row) {
myCell.addSomethingButton.enabled = false
} else {
myCell.addSomethingButton.addTarget(self, action: #selector(self.addSomething), forControlEvents: .TouchUpInside)
myCell.addSomethingButton.enabled = true
}
//disable cell clicking
myCell.selectionStyle = UITableViewCellSelectionStyle.None
return myCell
}
// I just Implemented this for demonstration purposes, you can merge this one with yours :)
func addSomething(button: UIButton) {
tappedButtonsTags.append(button.tag)
tableView.reloadData()
// ...
}
}
I Hope this helped.