Continuing from yesterday..
In my previous post, I mentioned that my application gives tasks a unique number so that I can easily reference them elsewhere, but that it might not be desirable to show this number at all times. In this situation, one can use a (subclass of) UITableViewCell and then when the cell is instantiated add a subview for the task number and move other fields accordingly to compensate. But I didn’t fancy programmatically adjusting such a view – the idea smelled bad. Instead I decided to create two XIBs and then choose between them when instantiating the cell. This is done as follows:
Create one XIB as normal, and a custom UITableViewCell subclass. In the XIB set the “Custom Class” field to the name of that subclass, and then create / synthesize IBOutlets and IBActions as normal. This is all standard stuff. In my app, I called the subclass TaskItemCell.
Duplicate the XIB, and add additional objects, adjusting (or removing) the existing ones as required. Create / synthesize IBOutlets and IBActions corresponding to these new objects. For my app, I named this XIB TaskItemCellWithID.xib.
At this stage, I had two XIBs which have the same custom class. Because this class has a set of properties that are common to both XIBs either one can be used. Here’s the method I use to populate the content of a cell, according to a specific task.
You’ll see that I don’t test which XIB is being used, because the class doesn’t care. In the UITableViewController‘s cellForRowAtIndexPath method, I merely check the user’s settings to determine which XIB to load:
Customising the Toolbar
View controllers that are managed by a navigation controller can set toolbar items for the view controller before it’s displayed or after it becomes visible. I wanted to have the ability to tab a “trash” icon and for completed tasks to be permanently deleted, however, I only wanted this icon to be displayed when viewing completed tasks. This helps ensure it’s a conscious action.
The method to establish the toolbar in my view controller draws the segmented control and the edit button (which is employed to allow tasks to be manually re-organised or individually deleted). Then, when the segmented control is changed, the corresponding method that responds to this change decides whether to insert the “trash” button.
UIBarItems include a tag property which allows applications to easily identify bar item objects. I use this to determine if the first item in the toolbar is the “trash” bar item or not, and add or remove it from the toolbar accordingly. Because I don’t care about any other tags in this toolbar, I’ve arbitrarily given it an NSInteger value of 10.
The UIActionSheet is a view that (for iPhone applications) usually slides up from the bottom of the screen. After it is created, it can then be displayed relative to a toolbar or tab bar. For this application all I needed to do was ensure that the sheet was displayed in accordance with the user’s preference, and then delete the tasks.
Because I hooked up NSFetchedResultsController to respond to deletions, when the tasks are deleted the display updates automatically – there’s no need to reload the table.
Here are the three methods which handle deletion of completed tasks. I explicitly extracted the code that invokes the deletion just in case there are other actions to be taken in future (e.g. animating the trash icon, as per the Mail application).