Each section can have a
header.
The header for our last section starts with a
"\n"
(newline character)
for extra vertical space.
Each section can also have a
footer.
As usual, it looked better in iOS 6:
AppDelegate
TableViewController
Our
TableViewController
acts as the
data
source
for the table view.
The
TableViewController
must therefore have the following methods.
We have already seen the first three in
States.
numberOfSectionsInTableView(_:)
returns 5 in this app
tableView(_:numberOfRowsInSection:)
tableView(_:cellForRowAtIndexPath:)
tableView(_:titleForHeaderInSection:)
and
tableView(_:titleForFooterInSection:)
.
These two methods are optional;
see exercise 1.
If you want a picture instead of a line of text,
see
tableView(_:viewForHeaderInSection:)
and
tableView(_:viewForFooterInSection:)
.
Our
TableViewController
also acts as the
delegate
for the table view.
The
TableViewController
must therefore have the following method.
tableView(_:didSelectRowAtIndexPath:)
.
This method is optional.
But if we didn’t have it,
the tabe view would do nothing when its cells
were touched.
footers
,
just like
headers
,
and a method named
tableView(_:titleForFooterInSection:)
, just like
tableView(_:titleForHeaderInSection:)
.
Unfortunately,
each footer looks like it’s part of the following header.
Perhaps the moral is that we should not have both headers and footers.
UITableViewStyle.Grouped
to
UITableViewStyle.Plain
in the
application(_:didFinishLaunchingWithOptions:)
method of the
application
delegate.
Launch the app and scroll the table view up and down.
It looks worse, doesn’t it?
override func sectionIndexTitlesForTableView(tableView: UITableView) -> [AnyObject]! { return ["EST", "CST", "MST", "PST", "Misc."]; //Return an array of Strings. } override func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int { //one-to-one correspondence between sections and section index titles return index; }
tableView(_:titleForHeaderInSection:)
,
tableView(_:titleForFooterInSection:)
,
and
sectionIndexTitlesForTableView(_:)
.
Let’s concentrate all the strings in one big array.
This is called
programming.
Change
zones
(the array of five arrays) to an array of five tuples.
Each tuple will contain four values.
The first value will be the header for the section.
The second value will be the footer for the section.
The third value will be
the index word along the right edge of the window.
The fourth value will be the array of state names.
let zones: [(header: String, footer: String, index: String, states: [String])] = [ ( "EST: Eastern Standard Time", //header "UTC -5:00", //footer "EST", //index [ "Alabama", "Connecticut", "Delaware", "Florida", "Georgia", "Indiana", "Kentucky", "Maine", "Maryland", "Massachusetts", "Michigan", "New Hampshire", "New Jersey", "New York", "North Carolina", "Ohio", "Pennsylvania", "Rhode Island", "South Carolina", "Tennessee", "Vermont", "Virginia", "West Virginia" ] ), ( "CST: Central Standard Time", //header "UTC -6:00", //footer "CST", //index [ "Arkansas", "Illinois", "Iowa", "Kansas", "Louisiana", "Minnesota", "Mississippi", "Missouri", "Nebraska", "North Dakota", "Oklahoma", "South Dakota", "Texas", "Wisconsin" ] ), ( "MST: Mountain Standard Time", //header "UTC -7:00", //footer "MST", //index [ "Arizona", "Colorado", "Idaho", "Montana", "New Mexico", "Utah", "Wyoming" ] ), ( "PST: Pacific Standard Time", //header "UTC -8:00", //footer "PST", //index [ "California", "Nevada", "Oregon", "Washington" ] ), ( "Miscellaneous", //header "Miscellaneous", //footer "Misc.", //index [ "Alaska", "Hawaii" ] ), ];
//in tableView(_:numberOfRowsInSection:) return zones[section].states.count;
//in tableView(_:cellForRowAtIndexPath:) assert(0 <= indexPath.section && indexPath.section < zones.count && 0 <= indexPath.row && indexPath.row < zones[indexPath.section].states.count); cell.textLabel!.text = zones[indexPath.section].states[indexPath.row];
//in sectionIndexTitlesForTableView var indices: [String] = [String](); //an empty array of Strings for zone in zones { indices.append(zone.index); } return indices;
//a shorter way to do the above //in sectionIndexTitlesForTableView return zones.map({$0.index});Even better, put the above array of dictionaries in a separate object. The class of the object should be named
Model
.