1

I'm working with Swift 4 trying to flip a card (that is a UIImageView) which is inside a UICollectionViewCell. I've two images and when I run the app, I can see one of them. But after the flip, what I get is a blue image instead of the second one.

Here's the code I've for the UICollectionViewCell class.

import UIKit

class CardViewCell: UICollectionViewCell {

    var cardFlipped = false
    var frontImage = UIImage(named: "image1")
    var backImage = UIImage(named: "image2")

    @IBOutlet var weak cardImage: UIImageView!
    @IBOutlet weak var flipCardButton: UIButton!

    @IBAction func flipCardAction(_ sender: Any) {
        flipCardAnimation()
    }

    func flipCardAnimation() {
        cardFlipped ? showFront() : showBack()
        contentView.reloadInputViews()
    }

    func showFront() {
        var image = cardImage.image
        image = frontImage
        flipCardButton.setImage(image, for: .normal)

        let transitionOptions = UIViewAnimationOptions.transitionFlipFromLeft
        UIView.transition(with: flipCardButton,
                          duration: 0.3,
                          options: transitionOptions,
                          animations: nil,
                          completion: nil)

        cardFlipped = true
    }

    func showBack() {
        var image = cardImage.image
        image = backImage
        flipCardButton.setImage(image, for: .normal)

        let transitionOptions = UIViewAnimationOptions.transitionFlipFromLeft
        UIView.transition(with: flipCardButton,
                          duration: 0.3,
                          options: transitionOptions,
                          animations: nil,
                          completion: nil)

        cardFlipped = false
    }
}

import UIKit

private let reuseIdentifier = "CardViewCell"

class GameViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {

    var collectionData = ["image2", "image2", "image2", "image2", "image2", "image2", "image2", "image2", "image2", "image2", "image2", "image2", "image2", "image2", "image2", "image2"]

    @IBOutlet weak var collectionView: UICollectionView!

    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView.delegate = self
        collectionView.dataSource = self

        // Set up the 4x4 grid
        let width = (view.frame.size.width - 60) / 4
        let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
        layout.itemSize = CGSize(width: width, height: width)
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        collectionView.reloadData()
    }

    // MARK: UICollectionViewDataSource

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return collectionData.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! CardViewCell

        cell.cardImage.image = UIImage(named: collectionData[indexPath.row])

        return cell
    }

    func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {

        let cell = collectionView.cellForItem(at: indexPath) as! CardViewCell

        let selectedImage = collectionData[indexPath.item]

        cell.flipCardAction(selectedImage)
    }
}
maxwell
  • 3,788
  • 6
  • 26
  • 40
Sil
  • 19
  • 2
  • FWIW, I'd suggest calling `setImage` inside the animation block of `UIView.transition(with:, ...)`. And if you make sure your button is of type `.custom`, you'll get the flipping animation you're looking for... – Rob Apr 22 '18 at 19:44
  • Just fix the image so it doesn't turn into a template image. So, if the front image is the problematic one: `image = frontImage?.withRenderingMode(.alwaysOriginal)` Or if the back image is the problematic one: `image = backImage?.withRenderingMode(.alwaysOriginal)` – matt Apr 22 '18 at 20:15
  • Many thanks for your answers, guys! I've changed the type button to `.custom` and now I don't see the blue image anymore. But I still have the same problem for switching the `image1` to `image2` in the `cardImage`. The flip animation works but the image never changes. I've tried both solutions (@Rob & @Matt) but I'm stuck with the same. Do you think that I should store the image in a `var` as I do with the `cardFlipped`? Where am I making the mistake? Many thanks once more! – Sil Apr 22 '18 at 22:47
  • You say `cardFlipped ? showFront() : showBack()`. So, if `cardFlipped` is `true`, you'll `showFront`. And at the end of `showFront`, you set `cardFlipped` to `true` (which is what it was before). Same if you started with `cardFlipped` to `false`. You'll call `showBack`, which just set it to `false` again. So, I don't see anything that will toggle from one image to the other. You'll just flip from `backImage` to `backImage`. Lol. – Rob Apr 22 '18 at 23:08
  • XD that's right, thanks again! But even though, the same problem is still there. Is there any "trick" that I should take into account with the UIImages inside a Collection View? Should I remove one in order to show the second one? I've updated the post with the code I've in the `UIViewController` as well (where the `collectionView` is placed). Would you mind to have a look to it, please? Lot of thanks for your help! – Sil Apr 23 '18 at 22:33

0 Answers0