mohammadreza
mohammadreza

Reputation: 235

iOS swift UIImageView change image in tableView cell

I have a strange problem in tableView Custom cell. for like Image action I write these code in Custom cell called FeedViewCell:

self.like.isUserInteractionEnabled = true
let CommenttapGestureRecognizer = UITapGestureRecognizer(target:self, action:#selector(likehandleTap))
self.like.addGestureRecognizer(CommenttapGestureRecognizer)

func likehandleTap(_ sender: UITapGestureRecognizer) {

    if self.like.image == UIImage(named: "like-btn-inactive") {

        self.like.image = UIImage(named: "like-btn-active")

    } else {
        self.like.image = UIImage(named: "like-btn-inactive")
    }
}

and TableViewController:

func tableView(_ tableView: UITableView, cellForRowAtIndexPath indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "FeedCell", for: indexPath) as! FeedViewCell

    return cell
}

but as you see in this video when I touch the like button in index 0 and change the image, the like button in index 3 change image also. can you guys tell me my mistake please?

thanks

Upvotes: 0

Views: 6086

Answers (3)

Himanshu Moradiya
Himanshu Moradiya

Reputation: 4815

Try code its working 100%

  var selectindex : Int?
  var selectedindex : NSMutableArray = NSMutableArray()
  @IBOutlet var tableview: UITableView!

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("LikeCell", forIndexPath: indexPath)

        let like: UIButton = (cell.viewWithTag(2) as! UIButton)
        let comment: UIButton = (cell.viewWithTag(3) as! UIButton)
        if selectedindex.containsObject(indexPath.row) {
                like.setBackgroundImage(UIImage.init(named: "like.png"), forState: .Normal)
        }else{
                like.setBackgroundImage(UIImage.init(named: "like (1).png"), forState: .Normal)
        }
       comment.setBackgroundImage(UIImage(named: "chat.png"), forState: UIControlState.Normal)
        like.addTarget(self, action: #selector(self.CloseMethod(_:event:)), forControlEvents: .TouchDown)
        comment.addTarget(self, action: #selector(self.CloseMethod1(_:event:)), forControlEvents: .TouchDown)

        return cell

    }



 @IBAction func CloseMethod(sender: UIButton, event: AnyObject) {

        let touches = event.allTouches()!
        let touch = touches.first!
        let currentTouchPosition = touch.locationInView(self.tableview)
        let indexPath = self.tableview.indexPathForRowAtPoint(currentTouchPosition)!
        selectindex = indexPath.row
        if selectedindex.containsObject(selectindex!) {
            selectedindex.removeObject(selectindex!)
        }else{
              selectedindex.addObject(selectindex!)
        }
        self.tableview.reloadData()
    }

Upvotes: 3

Jitendra Modi
Jitendra Modi

Reputation: 2394

Take one array

let arr : NSMutableArray = NSMutableArray()

And in tableview take button instead of image and set unlike image in button and set your images instead of my images

 func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 10
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)

        let btn = cell.viewWithTag(10) as! UIButton
        btn.addTarget(self, action: #selector(ViewController.connected(_:)), forControlEvents: .TouchUpInside)
        return cell
    }

    func connected(sender: UIButton){
        let buttonposition = sender.convertPoint(CGPointZero, toView: self.tblview)
        let index = self.tblview.indexPathForRowAtPoint(buttonposition)

        if !arr.containsObject((index?.row)!) {
            arr.addObject((index?.row)!)
            sender.setImage(UIImage(named: "ic_check.png"), forState: .Normal)
        }else
        {
            arr.removeObject((index?.row)!)
            sender.setImage(UIImage(named: "ic_uncheck.png"), forState: .Normal)
        }

    }

Upvotes: 0

Andrea Antonioni
Andrea Antonioni

Reputation: 30

That's why you are changing the image loaded in the imageView and then with method tableView.dequeueReusableCell you are reusing that cell with the changed image.

In iOS UITableView and UICollectionView apply the concept of reusable cells. They don't create one cell for every element of the array; they just create 3-4 cells and then they'll reuse it just changing the content inside. That's a great thing because it allows developers to create tables with hundreds of rows without having memory issues.

These are the steps followed by the tableView (and also collectionView) to show the array of elements:

  1. prepareForReuse
  2. cellForRowAtIndexPath
  3. willDisplayCell

To solve your problem you have just to check the like in the cellForRowAtIndexPath

Example:

func tableView(_ tableView: UITableView, cellForRowAtIndexPath indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "FeedCell", for: indexPath) as! FeedViewCell

    let model = arrayOfElements[indexPath.row]
    if model.isLiked {
        cell.like.image == UIImage(named: "like-btn-active")
    } else {
        cell.like.image == UIImage(named: "like-btn-active")
    }

    return cell
}

Upvotes: 0

Related Questions