2

I have a very simple demo which use UICollectionView to show a list of pictures, I use a customize cell class which contains an UIImage and a Label as below, there is no constraint.

customize cell on storyboard

Then I set the size of the cell in code as below. there are 3 columns on each row. all margins are set to 10.

// Calculate size of cell
    func collectionView(collectionView: UICollectionView,
                        layout collectionViewLayout: UICollectionViewLayout,
                               sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
        let totalSpace = marginLeft + marginRight + (colomnSpacing * CGFloat(numberOfItemsPerRow - 1))
        let size = Int((collectionView.bounds.width - totalSpace) / CGFloat(numberOfItemsPerRow))

        // 20 is for label height.
        return CGSize(width: size, height: size + 20)
    }

    // Section margin, if you only have one section, then this is the CollectionView's margin.
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
        return UIEdgeInsets(top: marginTop, left: marginLeft, bottom: marginBottom, right: marginRight) // top, left, bottom, right.
    }

    // Set row spacing
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
        return rowSpacing
    }

    // Set column spacing
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat {
        return colomnSpacing
    }

Here is the code used to set the image and label size. the image's width takes 1/3 width of the screen(exclude the column space), and the height equals to width. the label width was equal to image width, label's height was set to 20.

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! SearchImageCell

        // Set image size
        cell.imageView.frame = CGRect(x: 0, y: 0, width: cell.frame.width, height: cell.frame.height - 20)
        cell.imageView.contentMode = .ScaleAspectFill


        let currentItem = self.responseArray[indexPath.row]
        let imageUrl = currentItem["imgurl"] as? String
        let url = NSURL(string: imageUrl!)

        // Load the image
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
            let data = NSData(contentsOfURL: url!)
            dispatch_async(dispatch_get_main_queue(), { 
                cell.imageView.image = UIImage(data: data!)
            })
        }

        // Set label size
        cell.imageDesc.frame = CGRect(x: 0, y: cell.imageView.frame.height, width: cell.frame.width, height: 20)

        let shujia = currentItem["shujia"] as? String
        cell.imageDesc.text = shujia!
        cell.imageDesc.font = cell.imageDesc.font.fontWithSize(14)
        cell.imageDesc.textAlignment = .Center

        return cell
    }

The question is:

When I load the image first, the size of the image was incorrect, like below, you can see the image's height occupy entire height of the cell, and the label was not show up.

enter image description here

But, when I scroll down and up(This makes the cell being reused), the image was resized, and I got the correct result, this is what I want!

enter image description here

I tried to add some debug code to print the size of the cell/image/label, it seems all size was correct.

cell width:  100.0
cell height:  120.0
image width:  100.0
image height:  100.0
label width:  100.0
label height:  20.0

So, what's wrong?

There are some similar question on SO(here, here), but the answers not works for me, like

1. cell.layoutIfNeeded()
2. self.collectionViewLayout.invalidateLayout()
3. self.collectionView?.layoutIfNeeded()

Please help, let me know if you need more code.

Community
  • 1
  • 1
zdd
  • 8,258
  • 8
  • 46
  • 75

1 Answers1

0

set translatesAutoresizingMaskIntoConstraints to true for your image view and label. maybe it works.

Notes: when use IB it will set them to false

Wilson XJ
  • 1,750
  • 13
  • 14
  • I set this value to true, the label show up, but the image size still not correct, I change to use autolayout now, thank you all the same! – zdd Jul 02 '16 at 02:15