Rutger Huijsmans Rutger Huijsmans - 1 month ago 9
Swift Question

Animating NSLayoutConstraint while scrolling a UICollectionView

I've got a two labels above my UICollection and I need to to animate up when scrolling in the collection view. Basically giving the user the feeling that the screen is one big scroll able view.

My view looks like this in interface builder:

enter image description here

I've come up with the following code to make it look better on the smaller screens but it's not giving me the effect I want:

func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
if(velocity.y>0){
if Device.IS_3_5_INCHES() {
self.topConstraint.constant = -100
}
if Device.IS_4_INCHES() {
self.topConstraint.constant = -70
}
if Device.IS_4_7_INCHES() {
self.topConstraint.constant = 0
}
if Device.IS_5_5_INCHES() {
self.topConstraint.constant = 0
}
}else{
self.topConstraint.constant = 50
}
}


The problem with this code is that the screen now 'jumps' around instead of animate as if it where part of the collection view.

The other problem with this code that it 'jumps' back as soon as you start scrolling in the other direction. No matter if your at the top or bottom of the UIScrollView. Setting the TopConstraint back to 50 should only happy when you're at the top.

Answer

Here is how you can set the first two cells to be the width of the collection view:

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

let insets = collectionView.contentInset
let collectionViewWidth = collectionView.frame.width - (insets.left + insets.right + 1)
let collectionViewHeight = collectionView.frame.height - (insets.top + insets.bottom)

  switch indexPath.row {
    case 0, 1:

    return CGSize(width: collectionViewWidth, height: collectionViewHeight / 8)

      default:
     return CGSize(width: collectionViewWidth / 3, height: collectionViewHeight / 8)
    }
}

You can change how much you divide height by to get the desired ratio. Same with the default. So say you wanted all the cells after the first 2 to be 3 per row you would divide collectionViewWidth / 3

Then you can create a different collection view cell subclass to make the first two cells and in cellForItemAtIndexPath you would check to see which indexPath it is and set your cell accordingly.