简体   繁体   中英

Dynamic cell height in UICollectionView

I'm having a custom UICollectionViewCell which contains many objects but overall, it needs to connect to the database, grab stored image urls and populate a UIImageView by appending each photo (the number of photos is optional - from 1 to 10) to a UIStackView .

Now, I get everything except that the height of the cell is hard coded, so, it's not working. I'm not sure how to get the size though. Here's my code.

This is where the height is hardcoded.

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,   sizeForItemAt indexPath: IndexPath) -> CGSize
{
    let width = collectionView.bounds.width
    let size = CGSize(width: width, height: 800)
    return size
}

This is where the UIImageView is being setup. photoURLs is the array of the downloaded URLs from the database.

if let photoURLString = post?.photoURLs
{
    for urlString in photoURLString
    {
       let photoURL = URL(string: urlString)
       let imageView = UIImageView()
       imageView.sd_setImage(with: photoURL)
       imageView.contentMode = .scaleAspectFill
       imageView.clipsToBounds = true
       imageView.widthAnchor.constraint(equalTo: postImagesStackView.widthAnchor)
       postImagesStackView.addArrangedSubview(imageView)
       postImagesStackView.layoutIfNeeded()
     }
}

Also, how to leave a little bit of space between each photo? Like 1 point?

I think that you need to calculate cell height. In this case, sum images height before you call reload collectionView, or fix imageView height and multiplies images count with height.

Another solution is make cell for each image. Instead of stackview, you could using section and custom collectionview layout.

Like woosiki indicated, you could try just calculating a value based on image sizes returned. Once the you get the response and compute the full height, then call collectionView.reloadData() and reference that fullHeight property for each backing object. Something like below, though make it safer with if let/where and default/max height.

func collectionView(_ collectionView: UICollectionView, layout 
collectionViewLayout: UICollectionViewLayout,   sizeForItemAt 
indexPath: IndexPath) -> CGSize
{
    let imageObject = dataSource.items[indexPath.row]
    let width = collectionView.bounds.width
    let size = CGSize(width: width, height: imageObject.fullHeight)
    return size
}

For a border/spacing, could include slightly larger parent view if you end up including captions or metadata anyway or just try documentation example:

https://developer.apple.com/documentation/uikit/nslayoutanchor

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