简体   繁体   中英

Swift - get UIImage from UIColllectionViewCell

I have a collectionView where each cell contains a UIImage and an empty UIButton . How do I the picture that the user tapped on?

class ImageCollectionViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout{

    @IBOutlet weak var imageCollectionView: UICollectionView!

    let images: [UIImage] = [
        UIImage(named: "beerImage")!,
        UIImage(named: "christmasImage")!,
        UIImage(named: "goalImage")!,
        UIImage(named: "travelImage")!,
        UIImage(named: "rollerImage")!,
        UIImage(named: "giftImage")!,
        UIImage(named: "shirtImage")!,
        UIImage(named: "dressImage")!,

    ]

    let columnLayout = FlowLayout(
        itemSize: CGSize(width: 150, height: 150),
        minimumInteritemSpacing: 30,
        minimumLineSpacing: 10,
        sectionInset: UIEdgeInsets(top: 20, left: 20, bottom: 10, right: 20)
    )

    var colViewWidth: CGFloat = 0.0

    override func viewDidLoad() {

        self.imageCollectionView.collectionViewLayout = columnLayout

        super.viewDidLoad()

        imageCollectionView.dataSource = self
        imageCollectionView.delegate = self
    }

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "imageCell", for: indexPath) as! ImageCollectionViewCell

        cell.imageView.image = images[indexPath.item]
        cell.layer.cornerRadius = 2
        return cell
    }

    @IBAction func imageButtonTapped(_ sender: Any) {
        print("tapped")
    }


    @IBAction func closeButtonTapped(_ sender: Any) {
        let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let HomeViewController = storyBoard.instantiateViewController(withIdentifier: "HomeVC") as! ExampleViewController
                self.present(HomeViewController, animated: false, completion: nil)
    }
}

Update

In the end I would like to pass that image to another ViewController. I tried it this way but the picture isn't showing up in the other ViewController:

ViewControllerA

var tappedImage = UIImage()
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    tappedImage = images[indexPath.row]
}

var showPopUpView = true

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    print(showPopUpView)
    var vc = segue.destination as! ExampleViewController
    vc.pickedImage = self.tappedImage
    vc.ShowPopUpView = self.showPopUpView

}

ViewControllerB

    var pickedImage = UIImage()

override func viewDidLoad() {
        super.viewDidLoad()

        imagePreview.image = pickedImage

You could do something like this

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    imageToPass = images[indexPath.row]
}

Edit: As far as passing that image to your next view controller, one possible way is to add a property to your first and second view controllers for the image, set that image in your didSelectItemAt call, then pass it using prepare(for segue: UIStoryboardSegue, sender: Any?)

let imageToPass: UIImage?

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
   if segue.identifier == "identifier name here" {

       // Get the new view controller using segue.destination.
       if let destVC = segue.destination as? SecondViewController {
           // Pass the selected object to the new view controller.
           destVC.image = imageToPass
       }
   }
}

Duo to the conversation in comments:

The order of actions should be:

  1. User clicks on a cell
  2. Fetching the image according to the indexPath of the selected cell
  3. Setting it in a temporary variable ( tappedImage )
  4. Performing segue
  5. Pass the temporary image to the destination's temporary image ( pickedImage )
  6. Loading the destination's view
  7. Show the image.

Seems like you are missing one of these steps ( probably the step 3, since you are not calling performSegue in the ...didSelectItemAt indexPath... and it maybe not getting called at all! Try print something there and check if it's true )

Or you may disorder the flow ( probably you setting the image after destination's View is loaded and the result is to not seeing that. )

Debug:

Try printing all variables you have access (eg tappedImage , pickedImage , images[indexPath.row] , etc.) on each these 7 states and see where is the issue and where are you loosing the selected image reference

Possible issue

You are not using ...didSelectItemAt indexPath... to performSegue , Probably you have a UIButton for that, so the button is blocking the cell from getting selected.

Try this

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let image = images[indexPath.row]
    //Result image
}

(or) If you want to get image from button tap (Not recommended)

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
   let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "imageCell", for: indexPath) as! ImageCollectionViewCell

   cell.imageView.image = images[indexPath.item]
   cell.layer.cornerRadius = 2

   //Replace your button
   cell.yourButton.tag = indexPath.row
   cell.yourButton.addTarget(self, action: #selector(self.imageButtonTapped(_:)), for: .touchUpInside)
}

in button action

func imageButtonTapped(_ sender: UIButton) {
   let image = images[sender.tag]
   //Result image
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM