5

I have a UICollectionView of 20 cells with an imageView inside of them. when a user clicks on the correct cell, I draw another imageView in that cell (a correctCircle let's call it). This works fine.

But I also have a header in the UICollectionView where I ask the question they need to answer. After each click (wait 2 secs) the question should be updated, I have a function that updates the label for the Header text, this also works fine.

My problem is: In order to update the Header text, I have to call uicollectionView.reloadData() and whenever I do that, the UIImageView that I drew in the cell (the correctCircle) gets moved to another cell!

I've tried everything I can think of, including solutions in this thread: UICollectionView reloadData not functioning properly in iOS 7

But can't get it to work. Any ideas are more than welcome. Ideally I would only refresh the header and not the rest of the cells but there doesn't seem to be a way to do that.

Edit: slightly altering code based on comments, now I have 2 images in each cell and one is hidden, then I show it, instead of adding an imageView upon click.

Here's some relevant code:

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as CollectionViewIconCell    

        // bigIcon() just returns the animal's icon image
        cell.icon.image = animalsArray[indexPath.row].bigIcon()

        return cell
    }

override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
        // we cannot use a dequeueReusableCellWithReuseIdentifier, we need this
        let cell = collectionView.cellForItemAtIndexPath(indexPath) as CollectionViewIconCell

        if currentAnimal == self.correctAnimal {
            cell.circleImage.image = correctCircleImage
            cell.circleImage.hidden = false

            correctAnswers++

            // nextQuestion() simply loads the text that will go in the Header.label
            self.nextQuestion()
            self.collectionView!.reloadData()

        } else {
            self.answerCircle.image = UIImage(named: "wrongCircle")
            self.answerCircle.sizeToFit()
            cell.addSubview(answerCircle)

            self.nextQuestion()
            self.collectionView!.reloadData()
        }        
    }

Thanks.

PS

Reading some of the comments, maybe I'm not setting the text for the header correctly on a new question? I got all this code from tutorials, very new to UICollectionView so excuse my ignorance but is there a better way to refresh the header text? I can't get the header outside of the viewForSupplementaryElementOfKind function.

I should explain I have 2 different imageViews, one for correct answer and one for wrong answer because the circe for correct answer should remain while the one for wrong answer will be removed on each question and reused.

Community
  • 1
  • 1
kakubei
  • 5,321
  • 4
  • 44
  • 66

1 Answers1

8

Your problem is not in the code shown, it's in the code which returns the cell when requested, specifically because you aren't fully updating it by setting the status of both image views. So, when the cell is reused it has the wrong (old) settings from another row.

Really it's a data model and a cell design issue. The cell should always have 2 image views and you should just make visible or hide as required, and required should be determined from the data model which you update after each user selection and then reload (just update the cell when you can rather than fully reloading).

Wain
  • 118,658
  • 15
  • 128
  • 151
  • But the reloading issue is to get the header text to change, not to get the circle image to show, that currently shows without a reload. I will test what you suggest, but it doesn't preclude me from having to reload just to refresh the header. – kakubei Apr 03 '15 at 08:45
  • Reloading is the trigger for the issue because it updates all the cells. Presumably you reload because the header may change size with each question? Even if you don't really need to reload the header you should really fix the data model to hold the selection state. – Wain Apr 03 '15 at 08:48
  • Sure, I'll fix the cell issue, but, as I said, I need to reload or the text in the question doesn't change at all, not only the size but the text itself. Maybe I'm setting the text wrong in the Header? I'll show that code too. – kakubei Apr 03 '15 at 08:53
  • If you get the header view and update the contents it should change, you'd have to show the code but it's a separate thing – Wain Apr 03 '15 at 08:55
  • Curiously, fixing the issue you pointed out by including 2 images in the cell and then showing the image on a correct click, still the image will jump to another cell when reloaded! – kakubei Apr 03 '15 at 09:10
  • Yes, you must configure the image views when the cell is requested, not just when its tapped - this is a cell reuse issue – Wain Apr 03 '15 at 09:22
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/74402/discussion-between-kakubei-and-wain). – kakubei Apr 03 '15 at 09:30
  • 1
    I believe your last suggestion solved the problem. If you'd care to edit your answer to reflect that I'll accept it. I mean it's fine as it is, but being more specific I thing helps more people, the fact that I should check for the image's state on loading each cell is the key. Thanks! – kakubei Apr 03 '15 at 09:52