Swift Collection View: Phase 4/9

So far, you learned how to implement these features of the UICollectionView class:

Today you’ll learn how do the follow:

Shake the collection view cells when the user put it in edit mode.

Fyi, this is not a feature of theUICollectionView class; so you’ll implement it yourself in the iOS app we’ve been working on. Take a look at this QuickTime video, it show results of implementing the collection view cell shaking feature.

Create a New Branch

Ok, start things off by launching the SwiftCollectionView project in Xcode. Use the Source Control menu to create a new branch. Call it shake-collection-view-cells.

The Collection View Cell Shaking Code

Click the PhotoCell.swift file and add code shown in Listing 1. Add the code before the class closing } bracket.

Listing 1: PhotoCell.swift file code

// This function shake the collection view cells
func shakeIcons() {
  let shakeAnim = CABasicAnimation(keyPath: "transform.rotation")
  shakeAnim.duration = 0.05
  shakeAnim.repeatCount = 2
  shakeAnim.autoreverses = true
  let startAngle: Float = (-2) * 3.14159/180
  var stopAngle = -startAngle
  shakeAnim.fromValue = NSNumber(float: startAngle)
  shakeAnim.toValue = NSNumber(float: 3 * stopAngle)
  shakeAnim.autoreverses = true
  shakeAnim.duration = 0.2
  shakeAnim.repeatCount = 10000
  shakeAnim.timeOffset = 290 * drand48()

  //Create layer, then add animation to the element's layer
  let layer: CALayer = self.layer
  layer.addAnimation(shakeAnim, forKey:"shaking")
  shakeEnabled = true
}

// This function stop shaking the collection view cells
func stopShakingIcons() {
  let layer: CALayer = self.layer
  layer.removeAnimationForKey("shaking")
  self.deleteButton.hidden = true
  shakeEnabled = false
}

Switch to the MasterViewController.swift file and add this boolean declaration statement.

Listing 2: MasterViewController.swift file code

import UIKit

let reuseIdentifier = "Cell"

class MasterViewController: UICollectionViewController {

  @IBOutlet weak var editButton: UIBarButtonItem!
  var editModeEnabled = false
  var icon: PhotoCell!

Locate the cellForItemAtIndexPath() function and change the if statement code to the one shown in Listing 3.
Listing 3: MasterViewController.swift file code

if self.navigationItem.rightBarButtonItem!.title == "Edit" {
  icon.deleteButton.hidden = true
} else {
  icon.deleteButton.hidden = false
  icon.shakeIcons()
}

Scroll down to the editButtonTapped() function and add code shown in Listing 4.

Listing 4: MasterViewController.swift file code

@IBAction func editButtonTapped(sender: AnyObject) {
  if(editModeEnabled == false) {
    // Put the collection view in edit mode
    editButton.title = "Done"
    self.editButton.style = .Done
    editModeEnabled = true

    // Loop through the collectionView's visible cells
    for item in self.collectionView!.visibleCells() as [PhotoCell] {
      var indexPath: NSIndexPath = self.collectionView!.indexPathForCell(item as PhotoCell)!
      var cell: PhotoCell = self.collectionView!.cellForItemAtIndexPath(indexPath) as PhotoCell!
      cell.deleteButton.hidden = false // show all of the delete buttons
      cell.shakeIcons()
    }
  } else {
    // Take the collection view out of edit mode
    editButton.style = .Plain
    editButton.title = "Edit"
    editModeEnabled = false

    // Loop through the collectionView's visible cells
    for item in self.collectionView!.visibleCells() as [PhotoCell] {
      var indexPath: NSIndexPath = self.collectionView!.indexPathForCell(item as PhotoCell)!
      var cell: PhotoCell = self.collectionView!.cellForItemAtIndexPath(indexPath) as PhotoCell!
      cell.deleteButton.hidden = true  // Hide all of the delete buttons
      cell.stopShakingIcons()
    }
  }
}

Listing 5 shows the final set of code to add in the MasterViewController.swift file.

Listing 5: MasterViewController.swift file code

// This function is fired when the collection view begin scrolling
func collectionView(collectionView: UICollectionView, didBeginDisplayingCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
  if editModeEnabled == true {
    for cell in self.collectionView!.visibleCells() as [PhotoCell] {
      // Shake all of the collection view cells
      cell.shakeIcons()
    }
  }
}

// This function is fired when the collection view stop scrolling
override func collectionView(collectionView: UICollectionView, didEndDisplayingCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
  if editModeEnabled == true {
    for cell in self.collectionView!.visibleCells() as [PhotoCell] {
      // Shake all of the collection view cells
      icon.shakeIcons()
    }
  }
}

After adding Listing 5 code in the MasterViewController.swift file, run the app in the iOS iPhone/iPad simulator to test the collection view cell shaking feature.

That’s All Folks

That’s all for phase 4 of the SwiftCollectionView application. Next week, you will learn how to implement this feature in the app: highlight the collection view cell the user tapped. Until then, happy coding! 🙂