简体   繁体   中英

Changing button in cell when pressed

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM