dpstart
dpstart

Reputation: 1088

Table view cells mess up after scrolling

I've got a UITableViewCell, containing a specific of UIImages that I generate from code.

I've got this problem: the images are generated fine when I first load the view. However, if, for example, I scroll down and then I go back up, I find a completely different set of images.

I imagine this is a problem connected to the reusable cells, but I really don't know how to solve it.

for collabsImages in secImageUrls[indexPath.row] {

    dispatch_async(dispatch_get_main_queue()){
        let image = UIImageView()
        image.tag = i
        image.userInteractionEnabled = true
        image.frame = CGRectMake(CGFloat(10 + i*50 + 7*i), self.view.frame.height/2 - self.navigationController!.navigationBar.frame.height - 55, 40, 40)
        image.layer.cornerRadius = image.frame.width/2
        image.layer.masksToBounds = true
        image.sd_setImageWithURL(NSURL(string: collabsImages), placeholderImage: nil, options: [])
        cell1.addSubview(image)
        let didTapOnCollabImage = CollabsGestureRecognizer(target: self, action: "didTapOnCollabImage:", row: indexPath.row)
        image.addGestureRecognizer(didTapOnCollabImage)

        i++
    }
}

Here's the code for cellForRowAtIndexpath:

let cell1 : cellTableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as! cellTableViewCell


        tableView.allowsSelection = false
        cell1.profileImg.userInteractionEnabled = true

        let tappedOnImage = UITapGestureRecognizer(target: self, action: "tappedOnImage:")

        cell1.profileImg.tag = indexPath.row
        cell1.profileImg.addGestureRecognizer(tappedOnImage)


dispatch_async(dispatch_get_main_queue()) {

                cell1.profileImg.center = CGPointMake(35, 35)
                cell1.usernameLbl.frame = CGRectMake(cell1.profileImg.frame.maxX + 7, cell1.profileImg.frame.minY, self.view.frame.size.width/2, 20)
                cell1.usernameLbl.text = (self.jsonFeeds[indexPath.row]["author"] as? String)!
                cell1.titleLbl.text = (self.jsonFeeds[indexPath.row]["title"] as? String)
                cell1.titleLbl.frame = CGRectMake(cell1.profileImg.frame.maxX + 7, cell1.usernameLbl.frame.maxY + 7, self.view.frame.size.width-20, 20)

                let textLabel = UILabel(frame: CGRectMake(cell1.profileImg.frame.minX, cell1.titleLbl.frame.maxY + 20, self.view.frame.width-30, 90))
                //textLabel.center = CGPointMake(cell1.center.x, textLabel.center.y)
                textLabel.textAlignment = NSTextAlignment.Left
                textLabel.numberOfLines = 7
                textLabel.text = self.jsonFeeds[indexPath.row]["text"] as? String
                textLabel.backgroundColor = UIColor(red: 1/255, green: 109/255, blue: 127/255, alpha: 0.1)
                cell1.contentsView.addSubview(textLabel)

                let btn = UIButton()
                btn.frame = CGRectMake(cell1.frame.maxX - 150, textLabel.frame.maxY + 30, 130, 24)
                btn.layer.cornerRadius = 15
                btn.layer.borderWidth = 1
                btn.setTitle("MESSAGE", forState: UIControlState.Normal)
                btn.titleLabel?.font = UIFont(name: "HelveticaNeue-Thin", size: 14)
                btn.setTitleColor(UIColor.blackColor(), forState: .Normal)
                btn.layer.borderColor = UIColor.blackColor().CGColor

                cell1.contentsView.addSubview(btn)






            let block: SDWebImageCompletionBlock! = {

                (image: UIImage!, error: NSError!, cacheType: SDImageCacheType, imageURL: NSURL!) -> Void in

            }


            cell1.profileImg.sd_setImageWithURL(NSURL(string: self.imageUrls[indexPath.row]!), completed: block)

            }

            var i = 0
            for collabsImages in secImageUrls[indexPath.row] {

                if collabsImages != "This is a post"{



                    dispatch_async(dispatch_get_main_queue()){
                        let image = UIImageView()
                        image.tag = i
                        image.userInteractionEnabled = true
                        image.frame = CGRectMake(CGFloat(10 + i*50 + 7*i), self.view.frame.height/2 - self.navigationController!.navigationBar.frame.height - 55, 40, 40)
                        image.layer.cornerRadius = image.frame.width/2
                        image.layer.masksToBounds = true
                        image.sd_setImageWithURL(NSURL(string: collabsImages), placeholderImage: nil, options: [])
                        cell1.contentsView.addSubview(image)
                        let didTapOnCollabImage = CollabsGestureRecognizer(target: self, action: "didTapOnCollabImage:", row: indexPath.row)
                        image.addGestureRecognizer(didTapOnCollabImage)

                        i++
                    }
                }
            }
        }


        return cell1

Upvotes: 2

Views: 1317

Answers (2)

Siriss
Siriss

Reputation: 3767

First of all, you are dispatching to the main thread twice, and once in an existing dispatch call. You should not need to dispatch anything to the main thread in cellForRowAtIndexPath, unless you are doing background work you need to return, like a network fetch.

Second, you should set your image on the reusable cell to nil before the cell is loaded. image.image = nil right after you dequeue the cell. That might help make sure you are not reusing the image.

Apple and others have some very great tutorials on how to efficiently load images into a table view, also.

Upvotes: 2

Anand Prem
Anand Prem

Reputation: 437

Using tag along with reusable cells is a bad idea. Try to code the same without the help of tag. Giving indexpath.row as tag value cause weired issues. I think this will help

Upvotes: 0

Related Questions