Swift Collection View: Phase 3/9

So far, you’ve learned how to implement these features in the SwiftCollectionView workshop:

  • Display custom collection view cells in a single section of a collection view.
  • Enable the user to select a cell in the collection view and display its details in a view.

Today, you will learn how to implement this feature in the iOS app:

Delete a collection view cell by clicking a delete button of the collection view cell you want to delete

Fyi, this is not a feature of the UICollectionView class. The collection view class doesn’t have this feature; so you’ll have to implement it yourself, in the iOS app we’ve been working on.

As you can see in the video; you have to tap the navigation bar’s Edit button to put the collection view in “edit mode”, then tap the delete button that’s shown in the upper left corner of the cell you want to delete. Once you finish deleting the collection view cells, you have to tap the navigation bar’s Done button to return the collection view back to “default” mode. Isn’t that cool! 🙂

Create a New Branch

Implementing the collection view cell deletion feature in this phase of the Workshop will be super easy; so start by launching the SwiftCollectionView project in Xcode. Use the Source Control menu to add a new branch. Give it the name, collection-view-cell-deletion.

Create and Connect a Button On The Navigation Bar

You have to add a Bar Button Item on the Photo Scene’s navigation bar. Create and connect a function for it. Add code in the function to make the Bar Button Item an functional object.

Start by clicking the Main.storyboard file to load it in Interface Builder. Drag a Bar Button Item from the Object library and drop it on the right side of the Photos scene’s navigation bar. In the Attributes inspector, change the button’s Title attribute to Edit.

Use the Assistant editor to create and connect an IBOutlet variable called, editButton for the Edit button. Also, create and connect an IBAction function for the Edit button.

Switch to the standard editor and add this declaration statement at the top of the MasterViewController.swift file.

var editModeEnabled = false

The Bar Button Code

Listing 1 shows code to add in the deletePhotoCell() function. When you tap the navigation bar’s Edit button, the function’s code is executed.

Listing 1: MasterViewController.swift file code

 // MARK: The navigation bar's Edit button functions
    func deletePhotoCell(sender:UIButton) {
        // Put the index number of the delete button the use tapped in a variable
        let i: Int = (sender.layer.valueForKey("index")) as Int
        // Remove an object from the collection view's dataSource
        imageFileNames.removeAtIndex(i)

        // Refresh the collection view
        self.collectionView!.reloadData()
    }

    @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 // Hide all of the delete buttons
            }
        } 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
            }
        }
    }

Now, add code shown in Listing 2 in the collection view’s cellForItemAtIndexPath() function.

Listing 2: MasterViewController.swift file code

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        // Initialize the reusable Collection View Cell with our custom class
        icon = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as PhotoCell

        //Configure the collection view cell
        var imageFile = imageFileNames[indexPath.row]
        icon.imageView.image = UIImage(named: imageFile)
        var stringArray: Array = imageFile.componentsSeparatedByString(".")
        icon.caption.text = stringArray[0]

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

        // Give the delete button an index number
        icon.deleteButton.layer.setValue(indexPath.row, forKey: "index")

        // Add an action function to the delete button
        icon.deleteButton.addTarget(self, action: "deletePhotoCell:", forControlEvents: UIControlEvents.TouchUpInside)
        // Return the cell
        return icon
    }

Go ahead and add code shown in Listing 3 in the PhotoCell.swift file.

Listing 3: PhotoCell.swift file code

import UIKit

class PhotoCell: UICollectionViewCell {
    // The collection view cell's objects
    var imageView: UIImageView!
    var caption: UILabel!
    var deleteButton: UIButton!
    let deleteButtonImg: UIImage!

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override init(frame: CGRect) {
        super.init(frame: frame)

        // Create an ImageView and add it to the collection view
        imageView = UIImageView(frame: CGRect(x:30, y:12, width:55, height:55))
        imageView.contentMode = UIViewContentMode.ScaleAspectFill
        contentView.addSubview(imageView)

        // Create a Label view and add it to the collection view
        let textFrame = CGRect(x:5, y:67, width:100, height:35)
        caption = UILabel(frame: textFrame)
        caption.font = UIFont.systemFontOfSize(14.0)
        caption.textAlignment = .Center
        caption.numberOfLines = 2
        caption.lineBreakMode = NSLineBreakMode.ByWordWrapping
        caption.textColor = UIColor.whiteColor()
        caption.backgroundColor = UIColor.blackColor()
        contentView.addSubview(caption)

        // Create a UIButton
        deleteButton = UIButton(frame: CGRect(x: frame.size.width/10, y: frame.size.width/16, width: frame.size.width/4, height: frame.size.width/4))

        // Set the UIButton's image property
        deleteButtonImg = UIImage(named: "delete-icon")!
        deleteButton.setImage(deleteButtonImg, forState: UIControlState.Normal)

        // Add the UIButton to the collection view
        contentView.addSubview(deleteButton)
    }
}

You are done implementing the collection view cell deletion feature in the SwiftCollectionView app; so run it in an iOS simulator, put the collection view in “edit mode” by clicking the navigation bar’s Edit button. Delete a few or all of the collection view cells. Click the navigation bar’s Done button to take the collection view out of “edit mode”. See, how easy it was to implement the collection view cell deletion feature in the iOS SwiftCollectionView application.

That’s All Folks!

That’s all we have to do for phase 3 of the SwiftCollectionView app. Next week, you will learn how to implement this cool feature in the app: Shake the collection view cells when the user put it in edit mode. Until then happy coding! 🙂

  • Kacper Sienkiewicz

    Hi! Nice tutorial! Do you know how I can add shadow on the last cell?

  • Владислав Чапаев

    Awesome, you totally save my life, thanks.

  • Skylar Bjorn

    Hi! How would I be able to do this with Core Data? Thanks!! Being able to delete a cell from a collectionView out of Core Data is the last part of my app and it would mean the world to me if you help me. 🙂