Reputation: 1088
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
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
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