Stanford Cs193P: Developing Applications For Iphone 4, Ipod Touch, & Ipad Fall 2010
Stanford Cs193P: Developing Applications For Iphone 4, Ipod Touch, & Ipad Fall 2010
Developing Applications for iPhone 4, iPod Touch, & iPad Fall 2010
Today
UITableView UITableViewDataSource UITableViewCell UITableViewDelegate UITableViewController
Demo
Vocabulous
UITableView
Very important class for displaying data in lists
Its a subclass of UIScrollView. Lots and lots of customization via a dataSource protocol and a delegate protocol. Very efcient even with very large sets of data.
Often table views are pushed from each other to display a hierarchical data set. The column can be divided into sections for user-interface cleanliness or easy access to large lists.
UITableView
UITableViewStylePlain UITableViewStyleGrouped
UITableView
Plain Style
Table Header Section Header Table Cell Section Footer Section
Table Footer
Stanford CS193p Fall 2010
UITableView
Grouped Style
Table Header Section Header Table Cell Section Footer
Section
Table Footer
Stanford CS193p Fall 2010
UITableView
How do you get data into the table?
Delegated. Your MVCs Controller is almost always the dataSource for the UITableView.
@property (assign) id <UITableViewDataSource> dataSource;
That would be very inefcient. So, just like your GraphView, the UITableView only asks for data as it needs it. This means that if a row in the column is not on screen, the data is not asked for for that row. So that it can set the contentSize of itself (its a UIScrollView, remember).
But the table view needs to know the size of the data up front So the rst thing it will ask its dataSource is how many rows?
Actually, it will ask how many sections, then ask how many rows in each section. But only as each row comes on screen.
UITableViewDataSource
How many sections in the table?
- (NSInteger)numberOfSectionsInTableView:(UITableView *)sender;
An NSIndexPath is a way of specifying a section and row in one argument. indexPath.section is the section, indexPath.row is the row.
UITableView
Datasource
UITableView
numberOfSectionsInTableView:
Datasource
UITableView
numberOfSectionsInTableView:
Datasource 5
UITableView
tableView:numberOfRowsInSection:
Datasource
UITableView
tableView:numberOfRowsInSection:
Datasource 1
UITableView
tableView:cellForRowAtIndexPath:
Datasource
UITableView
tableView:cellForRowAtIndexPath:
Datasource
Cell with text John Appleseed
UITableViewDataSource
Example: Data is stored in an NSArray of NSString Just one long list of strings in this example
So no need to implement numberOfSectionsInTableView:.
/ section always 1 /
Stanford CS193p Fall 2010
UITableViewCell
So whats this UITableViewCell thing?
Its a UIView subclass for drawing a row in the table view.
Note that these are all readonly. They are lazily created when you call them. The detailTextLabel is like a little subtitle or other secondary text (depending on style). Obviously you wouldnt want to set the imageViews image property to a huge image.
Well talk about the reuse identier in a moment. First, lets talk about style and the above properties.
UITableViewCell
UITableViewCellStyleDefault UITableViewCellStyleSubtitle
UITableViewCellStyleValue1 UITableViewCellStyleValue2
UITableViewCell
@property (readonly) UILabel *textLabel; @property (readonly) UIImageView *imageView; @property UITableViewAccessoryType accessoryType;
@property (readonly) UILabel *detailTextLabel; - (UITableViewCell *)tableView:(UITableView *)sender cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = ...; / reuse or create / cell.textLabel.text = [myArray objectAtIndex:indexPath.row]; cell.imageView.image = [myImages objectAtIndex:indexPath.row]; cell.detailTextLabel.text = [mySubtitles objectAtIndex:indexPath.row]; cell.accessoryType = <gure out what kind of accessory type we want>; return cell; }
Stanford CS193p Fall 2010
UITableViewCell
UITableViewCellAccessoryDisclosureIndicator
UITableViewCell
UITableViewCellAccessoryDisclosureIndicator UITableViewCellAccessoryCheckmark
UITableViewCell
UITableViewCellAccessoryDisclosureIndicator UITableViewCellAccessoryCheckmark UITableViewCellAccessoryDetailDisclosureButton
- (UITableViewAccessoryType)tableView:(UITableView *)sender accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath { if ([[myArray objectAtIndex:indexPath.row] someMethod]) { return UITableViewCellAccessoryDetailDisclosureButton; } } - (void)tableView:(UITableView *)sender accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath { }
UITableViewCell
So whats this reuse identier business?
Its all about performance. We dont want to create 10,000 UITableViewCells for a table with 10,000 rows. We only want to create about 7 or 8 (which is how many are on screen at the same time). So we reuse them.
UITableViewCell
What else can you do to display a row besides text/image?
Turns out ... a lot!
You set this property to the view you want to appear in the accessory area.
Get the value of this property and add your custom view as a subview. Match your custom views frame to the contentViews & make sure your stretchiness is set right.
More UITableView
What else can the dataSource control?
Content of the headers and footers. Editability of the information in the table (inserting, rearranging, deleting rows).
This is the dataSource providing data for whats in the header (similar footer method of course).
Editing UITableView
Asking the dataSource to actually edit the underlying data
- (void)tableView:(UITableView *)sender commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath; UITableViewCellEditingStyleDeletion UITableViewCellEditingStyleInsertion
/ delete the data at the specied indexPath / / insert a new row at the specied indexPath /
You dont have to do the insert/delete, but if you do, you MUST update the UITableView (for example, using the method deleteRowsAtIndexPaths:withRowAnimation:).
Default is YES. Thus, if you dont implement, cells will be editable according to their editingStyle property whose value is retrieved from the UITableViews delegate (default is Deletion).
Reordering UITableView
Asking the dataSource to move rows in the underlying data
- (void)tableView:(UITableView *)sender moveRowAtIndexPath:(NSIndexPath *)sourcePath toIndexPath:(NSIndexPath *)destinationPath;
If you do not implement this, then cells cannot be reordered. If you implement it, you MUST move the row when asked (different than similar editing method).
Default is NO, so if you do not implement this, then cells cannot be reordered.
/ this is a settable property in UITableViewCell / The table view must be in editing mode for the reordering control to appear. Mode often activated via self.navigationController.rightBarButtonItem = self.editButtonItem. Can you be reordering and editing (deleting or inserting) at the same time? Stanford CS193p Yes, because swiping across a cell changes the reorder control to delete/insert control.
Fall 2010
UITableViewDelegate
All of the above was the UITableViews dataSource
But UITableView has another protocol-driven delegate called its delegate.
The delegate also lets you observe what the table view is doing
Especially responding to when the user selects a row.
UITableViewDelegate
Notication that a row is about to appear on screen
- (void)tableView:(UITableView *)sender willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;
Row selection
Heres where you put your code to handle selection of a row ...
- (void)tableView:(UITableView *)sender didSelectRowAtIndexPath:(NSIndexPath *)indexPath { SomeViewController *vcToPush = [[SomeViewController alloc] init]; vcToPush.someProperty = <something dependent on my data at indexPath>; [self.navigationController pushViewController:vcToPush animated:YES]; [vcToPush release]; }
Stanford CS193p Fall 2010
UITableViewDelegate
Usually selecting a cell pushes another view controller
So it is rare for a selection to stick in a UITableView. But it is not unheard of, especially with disclosure detail buttons.
UITableViewDelegate
Controlling the height of cells
- (CGFloat)tableView:(UITableView *)sender heightForRowAtIndexPath:(NSIndexPath *)indexPath;
UITableViewDelegate
Controlling the height of headers and footers
- (CGFloat)tableView:(UITableView *)sender heightForHeaderInSection:(NSInteger)section;
UITableViewController
Convenience class
Its a UIViewController which implements dataSource and delegate protocols of UITableView
Coming Up
Demo
Vocabulous
UITableView
which displays an NSDictionary of NSArrays of NSStrings Pushes an MVC which uses a UIWebView
Homework
No more Calculator! Places Lets the user browse popular photo spots from Flickr and look at photos from those spots.
UITabBarController UITableViewController UIImageView UIScrollView
Next Week