0

I create a UICollectionViewController and I want it to show three cells in each row. Each cell's width should be 1/3 of the whole screen. However, when I first enter the UICollectionViewController scene, all the cells are very small. When I scroll the screen, some cells become larger cells which have the expected size. enter image description here enter image description here enter image description here

Part of my code:

class imageCollectionViewController: UICollectionViewController {
private let reuseIdentifier = "photoCell"
var photos:albumCellModel?
override func viewDidLoad() {
    super.viewDidLoad()
    navigationController?.toolbarHidden = true

    if let layout = collectionView!.collectionViewLayout as? UICollectionViewFlowLayout {
        let itemWidth = view.bounds.width / 3.0
        let itemHeight = layout.itemSize.height
        layout.itemSize = CGSize(width: itemWidth, height: itemHeight)
        layout.invalidateLayout()
    }
}
override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {

    return 1
}
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    if let photos = photos
    {
        return photos.photoSet.count
    }
    return 0
}

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("photoCell", forIndexPath: indexPath) as! imageCollectionViewCell
    cell.imageView.image = photos?.photoSet[indexPath.row].image
    return cell
}
beasone
  • 1,073
  • 1
  • 14
  • 32

2 Answers2

1

I do encounter the same problem with my previous project. I managed to solve the problem by using this library. Snapkit. import the library in pod and implement it in cellForItemAtIndexPath

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

let cell = collectionView.dequeueReusableCellWithReuseIdentifier(cellIdentifier, forIndexPath: indexPath) as! TestCell
let width = self.view.bounds.size.width/2 - 10
    cell.imageView.snp_makeConstraints { (make) -> Void in
        make.width.equalTo(width)
        make.height.equalTo(3*width/2)
    }

return cell

}

Just put only top and leading constraint on the imageView in the storyboard. Hope it helps.

Syafiq Mastor
  • 178
  • 2
  • 10
0

Try to use the UICollectionViewDelegateFlowLayout delegate by changing your code like this:

class imageCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {

    private let reuseIdentifier = "photoCell"
    var photos:albumCellModel?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        navigationController?.toolbarHidden = true
    }

    override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        return 1
    }

    override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        guard let photos = photos else { return 0}
            
        return photos.photoSet.count
    }

    override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("photoCell", forIndexPath: indexPath) as! imageCollectionViewCell
        cell.imageView.image = photos?.photoSet[indexPath.row].image
        return cell
    }

    // New delegate method
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let numberOfItemsPerRow: CGFloat = 3
        let spacingBetweenCells: CGFloat = 0
        
        let totalSpacing = (2 * spacingBetweenCells) + ((numberOfItemsPerRow - 1) * spacingBetweenCells)
        
        let width = (collectionView.bounds.width - totalSpacing) / numberOfItemsPerRow
        let height: CGFloat = 200 // Put the value you desire
        
        return CGSize(width: width, height: height)
    }
lpizzinidev
  • 12,741
  • 2
  • 10
  • 29