/swift-parallax-scrolling-collectionview

Parallax Scrolling using UICollectionView and UICollectionViewCell in Swift in iOS 8

Primary LanguageSwiftMIT LicenseMIT

Parallax Scrolling using UICollectionView and UICollectionViewCell in Swift

Parallax scrolling using a moving background and a static foreground (alpha) images

Parallax scrolling is a big UI design trend these days. It is a technique where background images move by the camera slower than foreground images, creating an illusion of depth in a 2D scene and adding to the immersion.

In this example we are using UICollectionView which is subclass of a UIScrollView and two images per CollectionView cell UICollectionViewCell. Each image is contained inside an UIImageView within the cell:

  1. Background image which we are going to use for the parallax scrolling effect. The image here can be an image of some scenery
  2. Foreground alpha image which remains static on top of the background image. The foreground can be a transparent image with some text
override public func collectionView(collectionView: UICollectionView, 
            cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
   let cell:ParallaxCollectionViewCell = 
            collectionView.dequeueReusableCellWithReuseIdentifier(
                     "parallaxCellId", forIndexPath: indexPath) as! ParallaxCollectionViewCell
   cell.backgroundImage = UIImage(named: "\(images[indexPath.row])_background.png")!
   cell.foregroundImage = UIImage(named: "\(images[indexPath.row])_alpha.png")!
        
   return cell
}

The parallax scrolling is achieved by overriding UIScrollView delegate method scrollViewDidScroll where we change the Y axis offset of the background image view in relation to the parent cell:

override public func scrollViewDidScroll(scrollView: UIScrollView) {
   for cell in collectionView!.visibleCells() {
      var cell:ParallaxCollectionViewCell = cell as! ParallaxCollectionViewCell
      let yOffset:CGFloat = ((collectionView!.contentOffset.y - cell.frame.origin.y) / 
            cell.backgroundImageView.bounds.height) * ParallaxConstants.OffsetSpeed
      cell.setBackgroundImageOffset(CGPointMake(0, yOffset))
   }
}

We are using delegate collectionView:layout:sizeForItemAtIndexPath: from UICollectionViewDelegateFlowLayout to control the height of cells in our UICollectionView. In other words, how many cells should be visible to user at once:

public func collectionView(collectionView: UICollectionView, 
                           layout collectionViewLayout: UICollectionViewLayout, 
                           sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
   return CGSizeMake(self.view.bounds.width, 
                     self.view.bounds.height / ParallaxConstants.CellsPerCollectionView)
}

Inspired By

  1. Rikin Desai
  2. Venkat Palivela
  3. Cyril Wei