ContactsTableViewController.m (5513B)
1 #import "ContactsTableViewController.h" 2 #import "AddressBook.h" 3 #import "Network.h" 4 5 @interface ContactsTableViewController () { 6 Network *network_connection; 7 } 8 9 @property (strong, retain) AddressBook *address_book; 10 @property (strong, retain) NSMutableArray *cells; 11 @property (strong, retain) NSArray *section_to_letter; 12 13 @end 14 15 @implementation ContactsTableViewController 16 17 - (void)viewDidLoad 18 { 19 [super viewDidLoad]; 20 21 // Uncomment the following line to preserve selection between presentations. 22 // self.clearsSelectionOnViewWillAppear = NO; 23 24 // get a copy of the address book singleton 25 _address_book = [AddressBook shared_address_book]; 26 27 // we'll always have 26 or less letters in this dictionary 28 NSMutableDictionary *letter_to_contact_map = [NSMutableDictionary dictionaryWithCapacity:26]; 29 30 for (Contact *contact in _address_book.contacts) { 31 NSString *letter; 32 if (contact.last_name) 33 letter = [[contact.last_name uppercaseString] substringToIndex:1]; 34 else if (contact.first_name) 35 letter = [[contact.first_name uppercaseString] substringToIndex:1]; 36 else 37 // not sure if this can happen or not 38 continue; 39 40 if (letter_to_contact_map[letter] != nil) 41 [[letter_to_contact_map objectForKey:letter] addObject:contact]; 42 else { 43 NSMutableArray *tmp = [NSMutableArray arrayWithObject:contact]; 44 [letter_to_contact_map setObject:tmp forKey:letter]; 45 } 46 } 47 48 // get an array of first letters sorted lexicographically 49 _section_to_letter = [[letter_to_contact_map allKeys] 50 sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; 51 _cells = [[NSMutableArray alloc] init]; 52 53 for (NSString *letter in _section_to_letter) 54 [_cells addObject:[letter_to_contact_map objectForKey:letter]]; 55 56 network_connection = [Network shared_network_connection]; 57 } 58 59 - (void)didReceiveMemoryWarning 60 { 61 [super didReceiveMemoryWarning]; 62 // Dispose of any resources that can be recreated. 63 } 64 65 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 66 { 67 return [_cells count]; 68 } 69 70 - (NSInteger)tableView:(UITableView *)tableView 71 numberOfRowsInSection:(NSInteger)section 72 { 73 return [[_cells objectAtIndex:section] count]; 74 } 75 76 - (UITableViewCell *)tableView:(UITableView *)tableView 77 cellForRowAtIndexPath:(NSIndexPath *)indexPath 78 { 79 NSInteger section = [indexPath section]; 80 NSInteger row = [indexPath row]; 81 Contact *contact = [[_cells objectAtIndex:section] objectAtIndex:row]; 82 83 UITableViewCell *cell; 84 if (contact.first_name && contact.last_name) 85 cell = [tableView dequeueReusableCellWithIdentifier:@"contact_cell_two_name" forIndexPath:indexPath]; 86 else 87 cell = [tableView dequeueReusableCellWithIdentifier:@"contact_cell_one_name" forIndexPath:indexPath]; 88 89 if (contact.first_name && contact.last_name) { 90 UILabel *first = (UILabel *)[cell viewWithTag:1]; 91 UILabel *second_bold = (UILabel *)[cell viewWithTag:2]; 92 93 first.text = contact.first_name; 94 second_bold.text = contact.last_name; 95 } 96 else if (contact.first_name) { 97 // no last name 98 UILabel *first = (UILabel *)[cell viewWithTag:1]; 99 first.text = contact.first_name; 100 } 101 else if (contact.last_name) { 102 // no first name 103 UILabel *first = (UILabel *)[cell viewWithTag:1]; 104 first.text = contact.last_name; 105 } 106 else { 107 UILabel *first = (UILabel *)[cell viewWithTag:1]; 108 // neither first nor last names exist 109 // show first phone number if we have no other info 110 first.text = [contact.phone_numbers objectAtIndex:0]; 111 } 112 113 return cell; 114 } 115 116 // row was selected, toggle the accessory checkmark and call network functions 117 - (void)tableView:(UITableView *)tableView 118 didSelectRowAtIndexPath:(NSIndexPath *)indexPath 119 { 120 NSInteger section = [indexPath section]; 121 NSInteger row = [indexPath row]; 122 123 [tableView deselectRowAtIndexPath:indexPath animated:YES]; 124 125 UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 126 Contact *contact = [[_cells objectAtIndex:section] objectAtIndex:row]; 127 128 NSString *friend_phnum = [contact.phone_numbers objectAtIndex:0]; 129 if ([cell accessoryType] == UITableViewCellAccessoryNone) { 130 // Toggling the contact on, add friend 131 [network_connection send_message:friend_add contents:friend_phnum]; 132 [cell setAccessoryType:UITableViewCellAccessoryCheckmark]; 133 } 134 else { 135 // Toggling contact off, delete friend 136 [network_connection send_message:friend_delete contents:friend_phnum]; 137 [cell setAccessoryType:UITableViewCellAccessoryNone]; 138 } 139 140 NSLog(@"info: selected %@ %@ who has %lu phone numbers", 141 contact.first_name, contact.last_name, (unsigned long)[contact.phone_numbers count]); 142 } 143 144 // programatically assign section headers, in this case they're letters 145 - (NSString *)tableView:(UITableView *)tableView 146 titleForHeaderInSection:(NSInteger)section 147 { 148 return [_section_to_letter objectAtIndex:section]; 149 } 150 151 // needed to make the section header font bigger 152 - (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view 153 forSection:(NSInteger)section 154 { 155 UITableViewHeaderFooterView *header = (UITableViewHeaderFooterView *)view; 156 157 header.textLabel.font = [UIFont boldSystemFontOfSize:18]; 158 } 159 160 161 // these two delegates below put the "quick index" ribbon on the right side 162 - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView 163 { 164 return [[UILocalizedIndexedCollation currentCollation] sectionIndexTitles]; 165 } 166 167 - (NSInteger)tableView:(UITableView *)tableView 168 sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index 169 { 170 return [[UILocalizedIndexedCollation currentCollation] sectionForSectionIndexTitleAtIndex:index]; 171 } 172 173 @end