0

I have a vertical UICollectionView which contains 5 different types of cells. The 4 of them take the whole width of the UICollectionView, so the func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize gets the work done.

The other 2 are of the same size but their default position needs to be changed; I want them to be aligned from left to right, instead of the centered default.

Here's how I set up my UICollectionView:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    switch typesOfCellsArray[indexPath.row] {
    case .createVoiceRoom:
        return CGSize(width: collectionView.frame.width, height: 70)
    case .voiceRooms:
        let height: CGFloat = content.voiceRooms.count > 3 ? 256 : 128
        return CGSize(width: collectionView.frame.width, height: height)
    case .seeMoreVoiceRooms:
        return CGSize(width: collectionView.frame.width, height: 50)
    case .newStatus:
        let width = collectionView.frame.width / 4
        return CGSize(width: width, height: width + 40)
    case .status:
        let width = collectionView.frame.width / 4
        return CGSize(width: width, height: width + 40)
    }
}

Here's how they look:

enter image description here enter image description here

And here's what I want:

enter image description here enter image description here

I think I need to subclass UICollectionViewLayout to achieve that, but I've failed... Here's what I did:

class HomeCollectionViewLayout: UICollectionViewLayout {
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        guard let collectionView = collectionView else { return nil }
        let layoutAttributes = super.layoutAttributesForElements(in: rect)
    
        layoutAttributes?.forEach({ attributes in
            if collectionView.cellForItem(at: attributes.indexPath) is NewHomeStatusCollectionViewCell {
                let column = attributes.indexPath.row % 3
                attributes.frame.origin.x = CGFloat(column-1) * attributes.frame.width
            }
        })
    
        return layoutAttributes
    }
}

Of course, I have set this class as the UICollectionView layout. Any ideas?

Sotiris Kaniras
  • 520
  • 1
  • 12
  • 30

1 Answers1

0

You can insert each of you cell into separate section and then control following:

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets { }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat { }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { }
Mr.SwiftOak
  • 1,469
  • 3
  • 8
  • 19