How to maintain same line spacing for horizontal UICollectionviewCell after cell scaling transformation is applied

157 views Asked by At

I have one horizontal UICollectionview where I need to transform or reduced the size of unselected cells. I have given a common size in sizeForItem delegate function for all the cells. And I have given a minimumLine spacing to be maintained in between the cells. But the problem when re-scale the cell lets say (0.8 scalings) the space between the cells is getting wider and not maintaining the common size.

Here are the some code snippets for the collectionView,

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: 400, height: 400)


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

    return UIEdgeInsets(top: 0, left: 24, bottom: 24, right: 24)
}

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

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as? SomeCellClass
    cell.loadUI()
        
        if indexPath == selectedIndex {
            cell?.performScaleTransformation(reScale: false)
        }
        else{
            cell?.performScaleTransformation(reScale: true)
        }
    }
    return cell ?? UICollectionViewCell()
}

///This function is in Cell class SomeCellClass: UICollectionviewCell

func performScaleTransformation(reScale: Bool) {
   
    if reScale {
        UIView.animate(withDuration: 0.3, delay: 0.0, options: [ .curveEaseOut], animations: {
            self.transform = CGAffineTransform(scaleX: 0.8, y: 0.8)
        }, completion: nil)
    }
    else {
        UIView.animate(withDuration: 0.3, delay: 0.0, options: [ .curveEaseOut], animations: {
            self.transform = .identity
        }, completion: nil)
    }
}

The below is the output I m getting with this code,

enter image description here

From the attached screenshot you can see, how the spaces between cells are variying.

1

There are 1 answers

0
RPK On

I believe what is happening is that the transform is occurring independently of the layout of the collection view. The layout of the cell is not bound by the transform, so it does not affect the spacing.

You may be able to solve this by setting the size of the cells in the sizeForItemAt function. In that function, try and see if indexPath is in collectionView.indexPathsforSelectedItems and adjust the size in there.

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    if collectionView.selectedIndexPaths.contains(indexPath){
        return CGSize(width: 400.0, height: 400.0)
    } else {
        return CGSize(width: 320.0, height: 320.0)
    }
}

If you do this, you'll most likely have to invalidate the layout after each selection

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    collectionView.collectionViewLayout.invalidateLayout()
}

I'm not sure how animation would work with that or if the other cells would remain centered or not, but it's worth a shot.