TableView and TableViewController View that looks like the view on a telephone/address book The Master/Detail template provides the skeleton code for it MasterViewController extends the UITableViewController class Need to override various methods inherited from UITableViewController
Table View A table view displays a list of labels arranged in sections and rows We can decide the number of sections, the header for each section, and the rows of each section We can also retrieve what row of what section the user selected and execute some code based on that
Number of sections To define the number of sections, override numberOfSectionsInTableView:, return the desired number of sections (2 or 3 for example) -(NSInteger) numberOfSectionsInTableView(UITableView *) tableView { return 3; }
Number of rows per section To define the number of rows per section, override tableView:numberOfRowsInSection:, return the desired number of rows per section (use the section parameter); method header is -(NSInteger) tableView:( UITableView * ) tableView numberOfRowsInSection:( NSInteger ) section
Number of rows per section switch( section ) { case 0: // section 0 return 4; // 4 rows in section 0 case 1: // section 1 return 2; // 2 rows in section 1 case 2: // section 2 return 3; // 3 rows in section 2 }
Header of each section To define the title for each section, override tableView:titleForHeaderInSection:, define the desired title for each section; method header is -(NSString *) tableView:( UITableView * ) tableView titleForHeaderInSection: ( NSInteger ) section
Header for each section switch( section ) { case 0: // section 0 return @”CS courses”; case 1: // section 1 return @”CT courses”; case 2: // section 2 return @”AE courses”; }
Putting data in each table cell A cell of a table view is defined by 2 values: its section index and its row index within that section Example: a cell can be in section 0, row 3, or in section 1, row 0
Accessing each table cell The class NSIndexPath encapsulates the concept of how to access a cell in a table It has 2 properties, section and row If indexPath is aNSIndexPath object indexPath.section section indexPath.row row
Putting data in each table cell To put data in the table, override tableView:cellForRowAtIndexPath:, define the desired data for each row of each section; method header is -(UITableViewCell *) tableView:( UITableView * ) tableView cellForRowAtIndexPath : ( NSIndexPath * ) indexPath
Putting data in each table cell That method returns a UITableViewCell based on the NSIndexPath of that cell So inside the method, we create a UITableViewCell object, set the text inside it based on its index path, i.e. section and row, and return it
Putting data in each table cell The template already provides part of the code for that method (the part creating the UITableViewCell) A UITableViewCell has access to various properties and methods to manage its contents and behavior, for example image displayed and text
Putting data in each table cell Among other things, a UITableViewCell has a property called textLabel, a UILabel; so we need to set the text inside that label [[cell textLabel] setText:@”…”]; // OR cell.textLabel.text = @”…”; … depending on the value of indexPath.section and indexPath.row
Touching a table cell We may want to execute some code whenever the user touches a table cell (typically, go to the detail view) For this, we need to override the method tableView:didSelectRowAtIndexPath:
Touching a table cell The method header is - (void) tableView:(UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath Again, we can retrieve the section selected with indexPath.section and the row selected with indexPath.row
Go to Detail View Inside the tableView:didSelectRowAtIndexPath: method, we can add code to pass data to the DetailViewController (but it is only set for the iPad – more on that later)
iPhone vs iPad: 1 vs 2 View Controllers for detail View We may only want to have 1 View Controller for the detail view (as in the skeleton) Or we may want to have 2 View Controllers (i.e. add one): one for the iPad detail View and one for the iPhone detail View
Titles, .. - iPhone Edit in storyboard Change “Master” to … Change “Detail” to …
Titles, .. - iPad Title is set in splitViewController:willHideViewController:withBarButtonItem:forPopoverController: method change the title of barButtonItem if you want to change the title NSLocalizedString relates to locale (applicable to apps in several languages: English, Spanish, French, ..)
Master/Detail – Going Back The title shows up on the main page and the button (with the same title) shows up on the second page; clicking on it brings you back to the front page The Master/Detail template includes the corresponding code to provide this functionality
Passing data Inside the DetailViewController class, we can have instance variables and methods so that we can pass data to it from the root view controller Both view controllers can even share the same object (for example a TicTacToe object)
Passing data Most likely, the detail view will depend on two things: the section and the row selected by the user in the master view Have 2 int instance variables, section and row in the detail view controller Have a method setting them -(void) updateSection: (int) newSection Row: (int) newRow;
Passing data Set them to their new values whenever the user goes to the detail view, i.e. whenever the user clicks on a row of a section, i.e. whenever the method tableView:didSelectRowAtIndexPath: is called
Passing data [self.detailViewController setSection: indexPath.section Row: indexPath.row]; Now we can customize the detail view based on the values of section and row in the detail view controller
Passing data Where should you customize the view in the detail view controller class? Not every method is called every time the view shows; a lot of them are only called the first time the view is created can call viewWillAppear: (called every time we show the view, not just when the view is loaded in memory)
IPad Test the app with the iPad simulator detail view does not change Problem: We did not update the label (detailDescriptionLabel) inside the detail View
IPad self.detailDescriptionLabel.text = [NSString stringWithFormat: @”section %d row %d”, section, row]; detail View is updated correctly
IPad If you test the app inside the iPad simulator in vertical position, the popover does not dismiss when you make a selection we need to add code to dismiss it
IPad Inside the DetailViewController class, access the popover controller using self.masterPopoverController And use the dismissPopoverAnimated: method to dismiss it [self.masterPopoverController dismissPopoverAnimated: YES];
IPhone Problem: no data is passed when testing the app in the iPhone simulator Inside tableView:didSelectRowAtIndexPath:, self.detailViewController is null the call to updateRow:Section is a no-op
IPhone BUT prepareForSegue:sender: is called before tableView:didSelectRowAtIndexPath: AND we have access to the View Controller of the detail View via [segue destinationController]
IPhone Inside prepareForSegue:sender: self.detailViewController = [segue destinationController]; inside tableView:didSelectRowAtIndexPath: self.detailViewController is no longer null