iOS - List Basics

To implement the list view, I'll create a new class named LocationListViewController. This class will subclass UIViewController, and I will have XCode generate an associated xib file. Once created, I'll drag two controls onto the view: A TableView and a Toolbar. For the table view, I'll create a property named locationTableView. I'll also link the toolbar button to the method mapViewButtonClicked:. So far, my xib file looks as follows:



Looking closely at the associated interface file, I've made sure that this class conforms to the EventNotifier protocol. It also conforms to two other protocols: UITableViewDataSource and UITableViewDelegate. I'll elaborate on the associated methods below.

Other than the protocols, the public interface looks very similar to the map view interface.

The implementation file for LocationListViewController is as follows:

  1. #import "LocationListViewController.h"
  2. #import "FishingSpot.h"
  3.  
  4. @implementation LocationListViewController {
  5. NSMutableArray *locations;
  6. id<EventManager> eventManager;
  7. }
  8.  
  9. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
  10. {
  11. self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
  12. if (self) {
  13. locations = [[NSMutableArray alloc] init];
  14. }
  15. return self;
  16. }
  17.  
  18. -(void) setEventManager: (id <EventManager>)_eventManager {
  19. eventManager = _eventManager;
  20. }
  21.  
  22. -(void) setLocations: (NSMutableArray *) _locations {
  23. [locations removeAllObjects];
  24. [locations addObjectsFromArray:_locations];
  25. }
  26.  
  27. -(void) clearAll {
  28. [locations removeAllObjects];
  29. }
  30.  
  31. -(void)viewDidLoad {
  32. [super viewDidLoad];
  33. [self.locationTableView setDataSource:self];
  34. [self.locationTableView setDelegate:self];
  35. }
  36.  
  37. -(void)viewWillAppear:(BOOL)animated {
  38. [super viewWillAppear: animated];
  39. [self.locationTableView reloadData];
  40. }
  41.  
  42. - (void)viewDidUnload {
  43. [super viewDidUnload];
  44. [self clearAll];
  45. }
  46.  
  47. -(IBAction)mapViewButtonClicked:(id)sender {
  48. [eventManager handleEvent:EM_NAV_LOCAL_SPOTS_MAP withData:nil];
  49. }
  50.  
  51. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  52. return locations.count;
  53. }
  54.  
  55. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  56. static NSString *CellIdentifier = @"LocationListViewControllerCell";
  57. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
  58. if (cell == nil) {
  59. cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
  60. }
  61. FishingSpot* fs = (FishingSpot *)([locations objectAtIndex:[indexPath row]]);
  62.  
  63. [[cell textLabel] setText:fs.description];
  64. return cell;
  65. }
  66.  
  67.  
  68. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  69. // To be implemented in a future article...
  70. }
  71.  
  72. @end

Comments:

  • Line 5: The fishing spots are managed in a mutable array.
  • Lines 22 - 25: A public method for adding locations to the list.
  • Lines 27 - 29: A public method for removing locations from the list.
  • Lines 33 - 34: Once the view has loaded, specify that the delegate for the table's data is this class.
  • Lines 37 - 40: When the view will become visible, refresh the data.
  • Lines 47 - 49: When the 'Map View' button is clicked, inform the event manager that it should navigate to the map view controller.
  • Lines 51 - 70: These three methods are required by the UITableViewDataSource and UITableViewDelegate protocols. They are invoked to retrieve the contents of a row, and to notify the delegate when a row has been selected.
  • Line 51: This method is invoked by the table to get the total number of items in the table.
  • Lines 55 - 65: It's possible to have multiple widgets in a table cell. In this case, it will simply be the default text view. I populate the contents of the text view with the associated description of the fishing spot. (Line 56 helps conserve system resources by reusing existing cells if they've already been created but are not visible.)
  • Line 68: When a row is clicked, this method is invoked.

I've also updated AppDelegate.m: I've included the new view controller's header file, and in the method didFinishLaunchingWithOptions:, I've instantiated a location list view controller:

  1. //...
  2. locationListVC = [[LocationListViewController alloc] initWithNibName:@"LocationListViewController" bundle:nil];
  3. [locationListVC setEventManager:self];
  4. //...

In FishingMapViewController, I've added an additional button to the toolbar. When clicked, an event is fired to the event manager. Back in AppDelegate.m, I've updated handleEvent: as follows:

  1. //...
  2. case EM_NAV_LOCAL_SPOTS_MAP: {
  3. [self changeView:fishingMapVC];
  4. // ------- Load data for the map -------------
  5. LocationLoader *ll = [[LocationLoader alloc] init];
  6. [ll setDelegate:fishingMapVC];
  7.  
  8. if (BYPASS_SSL_CHECK) {
  9. [ll setAllowSSLBypass:YES];
  10. UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"SSL Warning"
  11. message:@"SSL Certification Bypass Active"
  12. delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
  13. [av show];
  14.  
  15. }
  16.  
  17. [ll loadLocations:[ffLoginVC userId] withToken:[ffLoginVC token]];
  18. break;
  19. }
  20.  
  21. case EM_NAV_LOCAL_SPOTS_LIST: {
  22. // For now, simply pull the values from the map view controller
  23. NSMutableArray *curSpots = fishingMapVC.getAllSpots;
  24.  
  25. [locationListVC setLocations: curSpots];
  26. [self changeView:locationListVC];
  27. break;
  28. }
  29. //...

This code populates the objects in the list, and then makes the list visible.

When launched, the new list view appears as follows:

I'll now turn to the Android implementation of a list view.