1.
2.
3.UITableView Protocols:How do we connect to all this stuff in our code?Via the UITableView’s datasource and delegate.
The delegate is used to control how the table is displayed.
The dataSource provides the data what is displayed inside the cells.
UITableViewController:Automatically sets itself as its UITableView’s delegate & dataSource.Also has a property pointing to its UITableView:
@property(nonatomic,strong)UITableView *tableView;
(this property is actually == self.view in UITableViewController!)
4.UITableViewDataSource:We have to implement these 3 to be a “dynamic”(arbitrary number of rows)table...
How many sections in the table?
How many rows in each section?
Give me a UITableViewCell to use to draw each cell at a given row in a given section.
5.How do we control what is drawn in each cell in a dynamic table?Each row is drawn by its own instance of UITableViewCell(a UIView subclass).
Here is the UITableViewDataSource method to get that cell for a given row in a section...
//NSIndexPath is just an object with two important properties for use with UITableView:row and section. -(UITableViewCell *)tableView:(UITableView *)sender cellForRowAtIndexPath:(NSIndexPath *)indexPath{ //get a cell to use (instance of UITableViewCell) UITableViewCell *cell; cell = [self.tableView dequeueReusableCellWithIdentifier:@“Flickr Photo Cell” forIndexPath:indexPath]; //set @properties on the cell to prepare to display //there are obviously other things you can do in the cell besides setting its text(detail text,image,checkmark,etc.). //See how we are using indexPath.section and indexPath.row to get Model information to set up this cell. cell.textLabel.text = [self getMyTitleForRow:indexPath.row inSection:indexPath.section]; return cell; }
The cells in the table are actually reused.When one goes off-screen,it gets put into a “reuse pool.”The next time a cell is needed,one is grabbed from the reuse pool if available.If none is available,one will be put into the reuse pool if there’s a prototype in the storyboard.Otherwise this dequeue method will return nil.
6.How does a dynamic table know how many rows there are?And how many sections,too, of course?
Via these two UITableViewDataSource methods...
-(NSInteger)numberOfSectionsInTableView:(UITableview *)sender; -(NSInteger)tableView:(UITableView *)sender numberOfRowsInSection:(NSInteger)section;
Number of sections is 1 by default.
No default for tableView:numberOfRowsInSection:,this is a required method in this protocol(as is tableView:cellForRowAtIndexPath:).
Do not implement these dataSource methods for a static table.UITableViewController will take care of that for you.
7.UITableViewDelegate:the delegate controls how the UITableView is displayed.Not what it displays(that’s the dataSource’s job).
The delegate also lets you observe what the table view is doing:The classic”will/did”sorts of things.
An important one is “user did select a row."
Usually we don’t need this because we simply segue when a row is touched.
But there are some occasions where it will be useful...
8.UITableViewDelegate method sent when row is selected:This is sort of like “tableView target/action”(only needed if you’re not segueing,of course).On the iPad,where the table might be on screen with what it updates,you might need this.
-(void)tableView:(UITableView *)sender didSelectRowAtIndexPath:(NSIndexPath *)path{ //go do something based on information about my model //corresponding to indexPath.row in indexPath.section }
Remember the little curled i?Clicking on this will not segue.Instead it will invoke this method in the UITableViewDelegate protocol...
-(void)tableView:(UITableView *)sender accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath{ //Do something related to the row at indexPath, //but not the primary action associated with touching the row }
9.UITableView Segue:The sender of prepareForSegue:sender:is the UITableViewCell.Use the important method indexPathForCell:to find out the indexPath of the row that’s segueing.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
//prepare segue.destinationController to display based on information
//about my Model corresponding to indexPath.row in indexPath.section
}
10.UITableViewController has an “activity indicator”built in.You get it via this property in UITableViewController...
@property(strong)UIRefreshControl *refreshControl;
Start it with...
-(void)beginRefreshing;
Stop it with...
-(void)endRefreshing;
11.What if your Model changes?
-(void)reloadData;
Causes the table view to call numberOfSectionsInTableView: and numberOfRowsInSection: all over again and then cellForRowAtIndexPath: on each visible cell.
Relatively heavyweight,but if your entire data structure changes,that’s what you need.
If only part of your Model changes,there are lighter-weight reloads,for examples...
-(void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animationStyle;