Implementing a Delete UI |

This is a companion discussion topic for the original entry at

@pasanpr, there are too many things to keep in mind for a beginner so instead of clarification this part of a lesson makes confusion. Please rework it in future to be more linear.=)

1 Like

@andreysvx Please let us know what you don’t understand exactly when you get a chance. Thank you!

I’m finding it a bit confusing myself too. I think for me, it’s when we get into overriding the setEditing method.

For one, I feel as though we’re introducing a bug by using indexPathsForVisibleItems since I believe it produces inconsistent results if you scroll after activating editing mode. I think it would also be helpful to explain when setEditing is called and how that helps change the background colour of the selected cell. In my head, it’s called when we tap the Edit button, but the fact that the background changes every time I tap after that point is a bit like black magic right now.

Additionally, the use of
collectionView.indexPathsForSelectedItems?.compactMap { $0 }.forEach { collectionView.deselectItem(at: $0, animated: true) }
gets a bit intense from a readability perspective. Maybe sticking to a more standard for-loop approach (or at least adding an indexPath in to the closure) could make it a bit more accessible for beginners here?

I think I understand the rest of it pretty well, mainly just those bits above that got my head spinning.

All valid critiques! indexPathsForVisibleItems was used primarily to reduce scope for the feature and not make this video too long. It wouldn’t be practical to use it if you expect the reason to scroll.

Set Editing

UIViewController has a method setEditing(_:animated:) that sets whether the view controller shows an editable view. The button you add to the nav bar has some default behavior in that when you tap it, it calls setEditing(_:animated:). The first argument to the method is a Boolean value indicating whether the view controller is in editing mode. By default when you tap the Edit button, the value supplied to setEditing(_:animated:) is true. On the flip side when you tap Done, the argument provided is false.

You then use this true/false value to determine when you are in editing mode. UIView instances have no definition of “edit mode” so you define a property isEditing to capture this state on each cell. Now the cell is aware whether it is being interacted with during edit mode.

Next you added a didSet property observer on isSelected. This allows you to invoke some side effects when the value of isSelected is set. Once a cell is selected (i.e., the value of isSelected is true) you can also check whether you are in edit mode by inspecting the value of isEditing and then change the background color appropriately.

Hope this helped.


I went with compactMap({ $0 }) because it helps get rid of that pesky optional and avoids double nesting before you get to the core logic. For those who prefer alternative syntax you would write:

if let indexPathsForSelectedItems = collectionView.indexPathsForSelectedItems {
  for indexPath in indexPathsForSelectedItems {
    collectionView.deselectItem(at: indexPath, animated: true)

You could also use a guard statement.