UITableViewCells

A UITableViewCell is a subclass of UIView, and each row in a UITableView is a UITableViewCell. (Recall that a table in iOS can only have one column, so a row only has one cell.) The UITableViewCells are subviews of the UITableView.

A cell itself has one subview – its contentView (Figure 10.8). The contentView is the superview for the content of the cell. It also can draw an accessory indicator. The accessory indicator shows an action-oriented icon, such as a checkmark, a disclosure icon, or a fancy blue dot with a chevron inside. These icons are accessed through pre-defined constants for the appearance of the accessory indicator. The default is UITableViewCellAccessoryNone, and that’s what we’ll use in this chapter. But you’ll see the accessory indicator again in Chapter 16. (Curious now? See the reference page for UITableViewCell for more details.)

Figure 10.8  UITableViewCell layout

UITableViewCell layout

The real meat of a UITableViewCell is the other three subviews of the contentView. Two of those subviews are UILabel instances that are properties of UITableViewCell named textLabel and detailTextLabel. The third subview is a UIImageView called imageView (Figure 10.9). For this chapter, we’ll only use textLabel.

Figure 10.9  UITableViewCell hierarchy

UITableViewCell hierarchy

In addition to its subviews, each cell has a UITableViewCellStyle that determines which subviews are used and their position within the contentView. Examples of these styles and their constants are shown in Figure 10.10.

Figure 10.10  UITableViewCellStyles

UITableViewCellStyles

Creating and retrieving UITableViewCells

In this chapter, each cell will display the description of a Possession as its textLabel. To make this happen, you need to implement the second required method from the UITableViewDataSource protocol, tableView:cellForRowAtIndexPath:. This method will create a cell, set its textLabel to the description of the corresponding Possession, and return it to the UITableView (Figure 10.11).

Figure 10.11  UITableViewCell retrieval

UITableViewCell retrieval

How do you decide which cell a Possession corresponds to? One of the parameters sent to tableView:cellForRowAtIndexPath: is an NSIndexPath, which has two properties: section and row. When this message is sent to a data source, the table view is asking, Can I have a cell to display in section X, row Y? Because there is only one section in this exercise, the table view only needs to know the row. In ItemsViewController.m, implement tableView:cellForRowAtIndexPath: so that the nth row displays the nth entry in the allPossessions array.

-​ ​(​U​I​T​a​b​l​e​V​i​e​w​C​e​l​l​ ​*​)​t​a​b​l​e​V​i​e​w​:​(​U​I​T​a​b​l​e​V​i​e​w​ ​*​)​t​a​b​l​e​V​i​e​w​
 ​ ​ ​ ​ ​ ​ ​ ​ ​c​e​l​l​F​o​r​R​o​w​A​t​I​n​d​e​x​P​a​t​h​:​(​N​S​I​n​d​e​x​P​a​t​h​ ​*​)​i​n​d​e​x​P​a​t​h​
{​
 ​ ​ ​ ​/​/​ ​C​r​e​a​t​e​ ​a​n​ ​i​n​s​t​a​n​c​e​ ​o​f​ ​U​I​T​a​b​l​e​V​i​e​w​C​e​l​l​,​ ​w​i​t​h​ ​d​e​f​a​u​l​t​ ​a​p​p​e​a​r​a​n​c​e​
 ​ ​ ​ ​U​I​T​a​b​l​e​V​i​e​w​C​e​l​l​ ​*​c​e​l​l​ ​=​
 ​ ​ ​ ​ ​ ​ ​ ​[​[​[​U​I​T​a​b​l​e​V​i​e​w​C​e​l​l​ ​a​l​l​o​c​]​ ​i​n​i​t​W​i​t​h​S​t​y​l​e​:​U​I​T​a​b​l​e​V​i​e​w​C​e​l​l​S​t​y​l​e​D​e​f​a​u​l​t​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​r​e​u​s​e​I​d​e​n​t​i​f​i​e​r​:​@​"​U​I​T​a​b​l​e​V​i​e​w​C​e​l​l​"​]​ ​a​u​t​o​r​e​l​e​a​s​e​]​;​

 ​ ​ ​ ​/​/​ ​S​e​t​ ​t​h​e​ ​t​e​x​t​ ​o​n​ ​t​h​e​ ​c​e​l​l​ ​w​i​t​h​ ​t​h​e​ ​d​e​s​c​r​i​p​t​i​o​n​ ​o​f​ ​t​h​e​ ​p​o​s​s​e​s​s​i​o​n​
 ​ ​ ​ ​/​/​ ​t​h​a​t​ ​i​s​ ​a​t​ ​t​h​e​ ​n​t​h​ ​i​n​d​e​x​ ​o​f​ ​p​o​s​s​e​s​s​i​o​n​s​,​ ​w​h​e​r​e​ ​n​ ​=​ ​r​o​w​ ​t​h​i​s​ ​c​e​l​l​
 ​ ​ ​ ​/​/​ ​w​i​l​l​ ​a​p​p​e​a​r​ ​i​n​ ​o​n​ ​t​h​e​ ​t​a​b​l​e​v​i​e​w​
 ​ ​ ​ ​P​o​s​s​e​s​s​i​o​n​ ​*​p​ ​=​ ​[​[​[​P​o​s​s​e​s​s​i​o​n​S​t​o​r​e​ ​d​e​f​a​u​l​t​S​t​o​r​e​]​ ​a​l​l​P​o​s​s​e​s​s​i​o​n​s​]​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​o​b​j​e​c​t​A​t​I​n​d​e​x​:​[​i​n​d​e​x​P​a​t​h​ ​r​o​w​]​]​;​

 ​ ​ ​ ​[​[​c​e​l​l​ ​t​e​x​t​L​a​b​e​l​]​ ​s​e​t​T​e​x​t​:​[​p​ ​d​e​s​c​r​i​p​t​i​o​n​]​]​;​


 ​ ​ ​ ​r​e​t​u​r​n​ ​c​e​l​l​;​
}​

A UITableView retains any UITableViewCell returned to it by tableView:cellForRowAtIndexPath:, which is why you can autorelease it here.

Build and run the application now, and you’ll see a UITableView populated with a list of random Possessions. Yep, it was that easy. You didn’t have to change anything about Possession – you simply changed the controller object and let the controller interface with a different view. This is why Model-View-Controller is such a powerful concept. With a minimal amount of code, you were able to show the same data in an entirely different way.

Reusing UITableViewCells

iOS devices have a limited amount of memory. If we were displaying a list with thousands of entries in a UITableView, we would have thousands of instances of UITableViewCell. And your long-suffering iPhone would sputter and die. In its dying breath, it would say You only needed enough cells to fill the screen... arrrghhh! It would be right.

To preserve the lives of iOS devices everywhere, you can reuse table view cells. When the user scrolls the table, some cells move offscreen. Offscreen cells are put into a pool of cells available for reuse. Then, instead of creating a brand new cell for every request, the data source first checks the pool. If there is an unused cell, the data source configures it with new data and returns it to the table view.

Figure 10.12  Reusable UITableViewCells

Reusable UITableViewCells

There is one problem: sometimes a UITableView has different types of cells. Occasionally, you have to subclass UITableViewCell to create a special look or behavior. However, different subclasses floating around the pool of reusable cells create the possibility of getting back a cell of the wrong type. You must be sure of the type of the cell returned to you so that you can be sure of what properties and methods it has.

Note that you don’t care about getting any specific cell out of the pool because you’re going to change the cell content anyway. What you want is a cell of a specific type. The good news is every cell has a reuseIdentifier property of type NSString. When a data source asks the table view for a reusable cell, it passes a string and says, I need a cell with this reuse identifier. By convention, the reuse identifier is simply the name of the cell class.

In ItemsViewController.m, update tableView:cellForRowAtIndexPath: to reuse cells:

-​ ​(​U​I​T​a​b​l​e​V​i​e​w​C​e​l​l​ ​*​)​t​a​b​l​e​V​i​e​w​:​(​U​I​T​a​b​l​e​V​i​e​w​ ​*​)​t​a​b​l​e​V​i​e​w​
 ​ ​ ​ ​ ​ ​ ​ ​ ​c​e​l​l​F​o​r​R​o​w​A​t​I​n​d​e​x​P​a​t​h​:​(​N​S​I​n​d​e​x​P​a​t​h​ ​*​)​i​n​d​e​x​P​a​t​h​
{​
 ​ ​ ​ ​/​/​ ​C​h​e​c​k​ ​f​o​r​ ​a​ ​r​e​u​s​a​b​l​e​ ​c​e​l​l​ ​f​i​r​s​t​,​ ​u​s​e​ ​t​h​a​t​ ​i​f​ ​i​t​ ​e​x​i​s​t​s​
 ​ ​ ​ ​U​I​T​a​b​l​e​V​i​e​w​C​e​l​l​ ​*​c​e​l​l​ ​=​
 ​ ​ ​ ​ ​ ​ ​ ​[​t​a​b​l​e​V​i​e​w​ ​d​e​q​u​e​u​e​R​e​u​s​a​b​l​e​C​e​l​l​W​i​t​h​I​d​e​n​t​i​f​i​e​r​:​@​"​U​I​T​a​b​l​e​V​i​e​w​C​e​l​l​"​]​;​

 ​ ​ ​ ​/​/​ ​I​f​ ​t​h​e​r​e​ ​i​s​ ​n​o​ ​r​e​u​s​a​b​l​e​ ​c​e​l​l​ ​o​f​ ​t​h​i​s​ ​t​y​p​e​,​ ​c​r​e​a​t​e​ ​a​ ​n​e​w​ ​o​n​e​
 ​ ​ ​ ​i​f​ ​(​!​c​e​l​l​)​ ​{​
 ​ ​ ​ ​ ​ ​ ​ ​c​e​l​l​ ​=​ ​[​[​[​U​I​T​a​b​l​e​V​i​e​w​C​e​l​l​ ​a​l​l​o​c​]​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​i​n​i​t​W​i​t​h​S​t​y​l​e​:​U​I​T​a​b​l​e​V​i​e​w​C​e​l​l​S​t​y​l​e​D​e​f​a​u​l​t​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​r​e​u​s​e​I​d​e​n​t​i​f​i​e​r​:​@​"​U​I​T​a​b​l​e​V​i​e​w​C​e​l​l​"​]​ ​a​u​t​o​r​e​l​e​a​s​e​]​;​
 ​ ​ ​ ​}​

 ​ ​ ​ ​P​o​s​s​e​s​s​i​o​n​ ​*​p​ ​=​ ​[​[​[​P​o​s​s​e​s​s​i​o​n​S​t​o​r​e​ ​d​e​f​a​u​l​t​S​t​o​r​e​]​ ​a​l​l​P​o​s​s​e​s​s​i​o​n​s​]​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​o​b​j​e​c​t​A​t​I​n​d​e​x​:​[​i​n​d​e​x​P​a​t​h​ ​r​o​w​]​]​;​


 ​ ​ ​ ​[​[​c​e​l​l​ ​t​e​x​t​L​a​b​e​l​]​ ​s​e​t​T​e​x​t​:​[​p​ ​d​e​s​c​r​i​p​t​i​o​n​]​]​;​

 ​ ​ ​ ​r​e​t​u​r​n​ ​c​e​l​l​;​
}​

(If you have a table view that uses multiple styles of the same type of cell, you can suffix the reuse identifier with the name of that style, e.g. UITableViewCell-Default.)

Reusing cells means that you only have to create a handful of cells, which puts fewer demands on memory. Your application’s users (and iOS devices everywhere) will thank you. Build and run the application. The behavior of the application should remain the same.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.14.131.212