Table Views UITableView
Overview Table view basics Tables display lists of data Each item in a tables list is a row Tables can have an unlimited number of rows Tables can only be one column wide (but see later slides) Reference: Apple Developer Reference
Views vs Cells A table view is a subclass of a view Technically it is a UITableView Each visible row in a table is an instance of a UITableViewCell Table view Table view cell
Table Data Table views do not store all the data Rather they just store data for the rows that are displayed They get their configuration data from the object that conforms to the UITabeViewdelegate protocol They get their row data from the object that conforms to the UITableViewDataSource protocol
Table Cells Each row is represented by a single UITableViewCell Each UITableViewCell object can be configured with an image, some text, an optional accessory icon If you need more data (or columns) in a cell you can create a subview Can do this programmatically Can do this in IB
Grouped Tables Plain Tables. The default style. May be indexed Grouped Tables. Each group is a set of rows embedded in a rounded rectangle. Can consist of a single group Each division in a table is known to your data source as a section In a grouped table, each group is a section In an indexed table, each indexed grouping of data is a section. E.g., names beginning with A, names beginning with B, etc.
Indexed vs Grouped Indexed TableGrouped Table
The app Well create a simple app with a single table view Later will create a navigation app that uses tables
Creating Create a new project Select single view application Choose a name, etc. Leave unchecked: include unit tests, use storyboards Check use automatic reference counting Choose a place to save Do not need to use git
What did you get? Look at the file navigator Normal appDelegate, viewcontroller, and nib
Creating the view Click on the nib to show IB Find a Table View in the library and drag to the view. The table view should automatically size itself to fill the entire view. Click on the view, bring up the connections inspector Under the outlets section drag from dataSource to Files Owner in the dock Under the outlets section drag from delegate to Files Owner in the dock This makes the viewController both the data source and delegate for the table.
Creating the controller in the Project Navigator click on the xxxViewController.h file and add the CMPViewController : (copy, nonatomic) NSArray This makes the view controller both the data source and the delegate of a table. The array will hold our data. Normally the data will reside in the model class not the controller class.
Creating the controller II in the Project Navigator click on the xxxViewController.m file and add the bold: #import BIDViewController (void)viewDidLoad { [super viewDidLoad]; @"Bifur", } The array will hold our table data
Creating the controller II in the Project Navigator click on the xxxViewController.m file and add the bold: (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [self.dwarves count]; } This method is called by the table when it needs to know how many rows are in the section (number of sections is 1 by default) We need as many rows as we have array entries.
Creating the controller II in the Project Navigator click on the xxxViewController.m file and add the bold: (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *SimpleTableIdentifier This method is called by the table when it needs a cell to display. We must return a UITableViewCell We identify the cells so that they can be reused later. Method continued on next slide….
Creating the controller II in the Project Navigator click on the xxxViewController.m file and add the bold: UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SimpleTableIdentifier]; } cell.textLabel.text = self.dwarves[indexPath.row]; return cell; We check to see if there is an unused cell of the correct type that we can reuse. We return this cell; it will be displayed as the next row If there was no leftover cell we have to create a new one. The label text is what shows up in the row. As table rows scroll out of view, they are placed into a queue of cells to be reused. If memory gets low, they are discarded. The indexPath variable contains the row (and section) number that the table will use this cell for. Use default style; there are others!
Run! Should see a table. But cant select anything yet!
More on Cells Add image Add icon image to Xcode (size 40x40, 80x80 for retina) (see Lectures >Programming >star.png) Change the method below (assuming icon has name star.png) UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SimpleTableIdentifier]; } UIImage *image = [UIImage cell.imageView.image = image; cell.textLabel.text = self.dwarves[indexPath.row]; return cell; }
More on Cells Add detail text Cells can have additional (detail) text. There are different cell types also. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:SimpleTableIdentifier]; } UIImage *image = [UIImage cell.imageView.image = image; if (indexPath.row < 7) { cell.detailTextLabel.text Disney"; } else { cell.detailTextLabel.text Tolkien"; } cell.textLabel.text = self.dwarves[indexPath.row]; return cell; } Must change the style of the cell for the subtitle to show up! Well use different subtitles for the first 7 rows (0-6). Subtitle Other styles: initWithStyle:UITableViewCellStyleValue1 initWithStyle:UITableViewCellStyleValue2
Detecting Row Selection Two events you can detect: When a row will be selected. Can prevent or change the selection When a row has been selected. Can react to the selection.
Detecting Row Selection When a row will be selected. Can prevent or change the selection Add to viewController.m: (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.row == 0) { return nil; } else { return indexPath; } Prevents row 0 from being selected.
Detecting Row Selection When a row has been selected. Put up alert box: Add to viewController.m: (void)tableView:(UITableView *)tableViewdidSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSString *rowValue = self.dwarves[indexPath.row]; NSString *message = [[NSString alloc] selected rowValue]; UIAlertView *alert = [[UIAlertView alloc] Selected!" message:message delegate:nil I Did" otherButtonTitles:nil]; [alert show]; [tableView deselectRowAtIndexPath:indexPath animated:YES]; } Now deselect the row A typical alert box Find the name of the dwarf for the selected row
Other modifications to cells See Beginning iOS 6 Development chapter 8 Set indent level of row Set font size, row height Customize table view cells Programmatically Using a nib file Add groups Add indexes Add navigation bar or search bar Detail disclosure buttons (chapter 9)