Fundamentals of TableViews

Duration

10 minutes

Tip: This is a group exercise, make sure to take advantage of the live instructor as you go through the exercise together.

Goals

The primary goal of this lab will be to add support for cell-reuse into our GetCell methods.

Required assets

There is a completed solution in the Exercise 5 folder. In addition, if you did not complete the prior exercise, you can use the completed solution from that exercise as a starting point here.

Challenge

You will be continuing from the prior exercise and adding code to your GetCell implementations to support cell reuse. You can make the changes in either the code-based TableView, the TableViewController, or both. The instructions and the completed solution has it implemented for both. Here are the high-level steps you will need to perform:

  1. Assign a reuse identifier - this is just a unique string. We only need one since we only have one cell style.
  2. Use the UITableView.DequeReusableCell method to retrieve a cell.
  3. In the code-based approach, where we don't have a storyboard-defined prototype cell, check for null and create the UITableViewCell in response - passing the reuse identifier to the constructor.
  4. In the Storyboard approach, assign the reuse identifier to the prototype cell in the designer to register it with the system.
  5. Initialize the cell properly based on whether it's a new cell or a reused cell.

Steps

Below are the step-by-step instructions to implement the exercise.

Adding reuse support to a code-based Table View

We will start with the code-based approach where we have a UITableViewSource defined.

  1. Open the source file with your UITableViewSource implementation and locate the GetCell method - this is where all our code changes will need to be performed.
  2. First, define a constant string (the completed solution uses "EmailCell") to be used as your cell reuse identifier. Since we will need to repeat this in a few places, using a constant is a good practice.
  3. Next, add a call at the top of the method to UITableView.DequeReusableCell, passing the reuse identifier. If it returns null, then use your existing code to create the cell instead, but pass the same reuse identifier to the constructor's second parameter (instead of null).
  4. Since we only need to set the fonts, colors, and accessory views when we create the cell initially, move that logic into the creation section where we did not get a cell back from the system. Only the dynamic values which change on a row-by-row basis must be done every time.
  5. To get the Table View to start reusing cells, we need a larger data set (i.e. more emails so we can scroll and trigger cell reuse). Modify the call to the EmailServer constructor and pass in 1000 - it defaults to only 10 messages.
  6. Run the application. You shouldn't see any change to the behavior; however, on a physical device with a lot of emails, it will likely run more smoothly due to the cell reuse.
  7. One last optimization we should make: we currently assign an image each time, but now that the cells are being reused, we are leaving the old images around for the garbage collector to deal with. These might represent large resources (they don't really right now), so we should free them as soon as we are done with them. If the cell was returned by the DequeReusableCell call, then check to see if the ImageView.Image property is non-null and if so, call Dispose on it. You can check the code hint below for the final method implementation.
  8. Show Code

Adding reuse support to a Storyboard based cell

Let's make the same changes to our Storyboard approach. The key difference here is that the cell will be inflated by the system automatically because the reuse identifier is assigned to the Storyboard cell.

  1. Open the Main.storyboard file.
  2. Set the storyboard-based View Controller as the initial View Controller. Recall that an easy way to do this is to drag the "handle" from its current position next to the code-based View Controller so it points to the storyboard-based View Controller.
  3. Open the Main.storyboard and select the prototype cell in the Table View Controller - just click on the white rectangle at the top of the Table View.
  4. In the Properties, set the Identifier value to "EmailCell".
  5. With the cell still selected, change the Style to be Subtitle - this is what we were doing before in code, but now we'll use the designer to make the same changes.
  6. The cell should now have two labels in it - you can select each label and set the fonts and colors here in the designer.
    • For the title, use 14pt Helvetica Light.
    • For the subtitle, use 12pt Helvetica Light in a light-gray color.
  7. Open the TableViewController.cs source file and locate the GetCell method - this is where all our code changes will need to be performed.
  8. Start by adding a call at the top of the method to UITableView.DequeReusableCell, passing the reuse identifier. You can use the same constant string you defined earlier, or re-define it here ("EmailCell"), or just use the literal string in the call. We only need it once in the code with this approach.
  9. You can remove all the code which sets colors and fonts - the storyboard will do that when it inflates the cell.
  10. You do need the code that locates the correct EmailItem and loads the data into the appropriate views. If you don't have that code in this implementation, you can copy it from the code-behind version of your GetCell method.
  11. Modify your call to the EmailServer constructor and pass in "1000".
  12. As before, we should dispose the image - in this case we can just check for a non-null image and dispose it, no need to test the cell.
  13. The final method implementation is in the below code hint.
  14. Show Code

  15. Run the application. You shouldn't see any change to the data presentation since this is a performance optimization.

Summary

In this exercise, you have optimized the implementation of the two GetCell methods to support cell reuse.

Go Back