I'm trying to change the color of a button when pressed. Currently its inside a table view cell.
The way I'm doing it is adding as so:
@IBAction func upVote(sender: AnyObject) {
sender.setImage(UIImage(named: "bUpVote"), forState: .Normal)
}
and this is done inside the cell class (not the view controller class).
It works, but the change also applies to every third cell that follows it for the rest of the table. Any work around? Thanks!
There are many way to solve this issue, one of the method is as follows
Add this to your customCell class,
@objc protocol MyTableViewCellDelegate {
func controller(controller: MyTableViewCell, button: UIButton, selectedButtonIndexPath : NSIndexPath)
}
class MyTableViewCell: UITableViewCell {
var delegate: AnyObject?
var indexPath : NSIndexPath?
@IBOutlet weak var button: UIButton!//outlet of button
button Action
@IBAction func buttonAction(sender: UIButton)//IF the sender type is AnyObject, you have to change it as UIButton
{
self.delegate?.controller(self, button: sender, selectedButtonIndexPath: indexPath!)
}
Add this to your ViewController class that has UITableView
class MyTableViewController: UITableViewController, MyTableViewCellDelegate { // I created a subClass of UITableViewController, your's may be different
var arraySelectedButtonIndex : NSMutableArray = []//global declaration
Since i created my custom cell using xib, in viewDidLoad()
tableView.registerNib(UINib(nibName: "MyTableViewCell", bundle: nil), forCellReuseIdentifier: "CustomCell")//Since, I use custom cell in xib
define delegate of custom cell by adding this
func controller(controller: MyTableViewCell, button: UIButton, selectedButtonIndexPath : NSIndexPath)
{
if(arraySelectedButtonIndex .containsObject(selectedButtonIndexPath)==false)
{
arraySelectedButtonIndex.addObject(selectedButtonIndexPath)
button.setImage(UIImage(named: "bUpVote") , forState: .Normal)
}
else
{
arraySelectedButtonIndex.removeObject(selectedButtonIndexPath)//If you need to set Deselect image
button.setImage(UIImage(named: "deselectImage") , forState: .Normal)//If you need to set Deselect image
}
}
In tableView dataSource ( cellForRowAtIndexPath
)
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("CustomCell", forIndexPath: indexPath) as! MyTableViewCell
cell.delegate = self
cell.indexPath = indexPath
if(arraySelectedButtonIndex .containsObject(indexPath))
{
cell.button.setImage(UIImage(named: "bUpVote"), forState: .Normal)
}
else
{
cell.button.setImage(UIImage(named: "deselectImage"), forState: .Normal)//If you need to set Deselect image
}
return cell
}
It's because cells are reused by the tableView. if you need to persist the state of subviews in the cell, you need to update your data source and reflect the changes in cellForRowAtIndexPath method.
This is not the way to do it. You store the state of the button in your model. Eg: say store the item's upvoted status in your model :
class Post
{
var title : String
var upvoted : Bool
}
How to get the index path ?
Move the IBAction method on your custom tableview subclass. Add a property called delegate to the cell and set it to your controller in cellForRowAtIndexPath:
. Now in the action method inform the delegate.
I have described this in detail here : https://stackoverflow.com/a/32250043/1616513
Now when the user upvotes you update the model :
@IBAction func upVotedInCell(sender: UITableViewCell) {
var indexPath = self.tableView.indexPathForCell(sender)
self.items[indexPath].upvoted = true
self.tableView.reloadRowsAtIndexPaths([indexPath],UITableViewRowAnimation.None)
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.