Enkha
Enkha

Reputation: 430

Get Cell Image from UICollectionView in Swift 4

I created a UICollectionView and created a Custom cell.

I put the image in the custom cell and returned the cell.

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
    guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "HomeCollectionViewCell", for: indexPath) as? HomeCollectionViewCell,
    let arts = self.artList else { return HomeCollectionViewCell() }

    if arts.count > indexPath.row
    {
        let model = arts[indexPath.row]

        cell.imgView.sd_setImage(with: URLHelper.createEncodedURL(url: model.url), completed: nil) // set cell image
    }

    return cell
}

Then, we execute a function that sets the vertical size of the cell.

func collectionView(_ collectionView: UICollectionView, heightForPhotoAtIndexPath indexPath: IndexPath) -> CGFloat
{
    // get cell information

    return // cell Image Height
}

However, I do not know how to get cell information (cell vertical value) from this function.

What should I do?

Upvotes: 0

Views: 2478

Answers (6)

Sateesh Yemireddi
Sateesh Yemireddi

Reputation: 4409

As the image inside model needs to be reused in following methods so download it in the model itself with rest of the data from API service.

func collectionView(collectionView: UICollectionView,
                    heightForImageAtIndexPath indexPath: IndexPath,
                    withWidth: CGFloat) -> CGFloat

&

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

Code for downloading the image in the model:

if let url = URL(string: "image_url_string") {
    if let data = try? Data(contentsOf: url) {
        image = UIImage(data: data)
    }
}

In viewController's PinterestLayoutDelegate:

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

    guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "HomeCollectionViewCell", for: indexPath) as? HomeCollectionViewCell,
        let arts = self.artList else { return HomeCollectionViewCell() }

    if arts.count > indexPath.row {
        let model = arts[indexPath.row]

        cell.imgView.image = model.image //Which is downloaded in the model itself.
    }

    return cell
}

func collectionView(collectionView: UICollectionView, heightForImageAtIndexPath indexPath: IndexPath, withWidth: CGFloat) -> CGFloat {

    // get image information
    let image = self.artList[indexPath.item].image

    return image.height(forWidth: withWidth) // cell Image Height
}

And don't forget to use this extension:

public extension UIImage {
    public func height(forWidth width: CGFloat) -> CGFloat {
        let boundingRect = CGRect( x: 0, y: 0, width: width, height: CGFloat(MAXFLOAT))
        let rect = AVMakeRect(aspectRatio: size, insideRect: boundingRect)
        return rect.size.height
    }
}

Upvotes: 0

user8713838
user8713838

Reputation:

i think you can solve the issue by making a public array of your cells then adding each cell in to the array just before you return the cell...

there you can get the created cells array and you can get any details related to the created cells by validating the cell array. Hope it will help

 var cellArray : [HomeCollectionViewCell] = [HomeCollectionViewCell]()

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "HomeCollectionViewCell", for: indexPath) as? HomeCollectionViewCell,
let arts = self.artList else { return HomeCollectionViewCell() }

if arts.count > indexPath.row
{
    let model = arts[indexPath.row]

    cell.imgView.sd_setImage(with: URLHelper.createEncodedURL(url: model.url), completed: nil) // set cell image
}
self.cellArray.append(cell)
return cell
}

Upvotes: 0

Satish
Satish

Reputation: 2043

Use this to get the cell.

let cell = collectionView.cellForItem(at: indexPath)

But not sure why you need a cell here. If you want a dynamic height cell this is not needed at all, you should use autolayout

Upvotes: 0

Mahendra
Mahendra

Reputation: 8924

You can use guard-let here.

func collectionView(_ collectionView: UICollectionView, heightForPhotoAtIndexPath indexPath: IndexPath) -> CGFloat {

  guard let cell = collectionView.cellForItem(at: indexPath) as? HomeCollectionViewCell else { 
   return 0
  }

  //do something with cell
  return 80//calculate height of cell
}

Upvotes: 0

DionizB
DionizB

Reputation: 1507

You can do it like this:

if let cell = collectionView.cellForItem(at: indexPath) as? HomeCollectionViewCell { 
    return cell.imgView.frame.height
}
return 0

Upvotes: 2

Natarajan
Natarajan

Reputation: 3271

You can get the cell details as like below example.

func collectionView(_ collectionView: UICollectionView, heightForPhotoAtIndexPath indexPath: IndexPath) -> CGFloat
{
    // get cell information

    if let cell = collectionView.cellForItem(at: indexPath) as? HomeCollectionViewCell{

        let image = cell.imgView.image

        return min(image.size.height, 300.0) // cell Image Height
    }


    return 0// cell Image Height
}

Upvotes: 0

Related Questions