I'm trying to use a UISearchDisplayController to search with CLGeocode as the user types, for use with an MKMapView. My view controller has only two things in it - the UISearchBar associated with the UISearchDisplayController and the map view. I'm using a Storyboard.
Normally one would do this with an underlying table view and would declare a prototype cell there, but there seems to be no way of doing that here since I don't have the table view. So I created a subclass of UITableViewCell called SearchTableViewCell, with associated nib.
The nib contains one label, with this outlet connected:
@interface SearchTableViewCell : UITableViewCell
@property (unsafe_unretained, nonatomic) IBOutlet UILabel *textLabel;
@end
I load the nib in viewDidLoad:
[self.searchDisplayController.searchResultsTableView registerNib:[UINib nibWithNibName:@"SearchTableViewCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"CellIdentifier"];
I get the data from CLGeocoder like this:
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller -(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
[self.geocoder geocodeAddressString:searchString completionHandler:^(NSArray *placemarks, NSError *error) {
self.placemarks = placemarks;
[self.searchDisplayController.searchResultsTableView reloadData];
}];
return NO;
}
And my tableview code looks like this:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.placemarks count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *kCellID = @"CellIdentifier";
SearchTableViewCell *cell = (SearchTableViewCell *)[tableView dequeueReusableCellWithIdentifier:kCellID forIndexPath:indexPath];
CLPlacemark *placemark = self.placemarks[indexPath.row];
NSString *addressString = CFBridgingRelease(CFBridgingRetain(ABCreateStringWithAddressDictionary(placemark.addressDictionary, NO)));
cell.textLabel.text = addressString;
return cell;
}
The search part is working - when I get to cellForRowAtIndexPath there is data in self.placemarks. However, the line that dequeues a new cell is failing with an exception the first time it's called:
'NSUnknownKeyException', reason: '[<NSObject 0x1a840d40> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key textLabel.'
My cell object is compliant for textLabel, but I'm wondering about that NSObject there in the error message - is the object being returned not a SearchTableViewCell? It is configured in IB to use the correct class. And why is the dequeue method checking for textLabel anyway? I'm pretty sure I've had custom table cells before that had no textLabel field.
Any suggestions on where I've gone wrong?
It turned out that somehow, I had two connections to textLabel - one proper one to the IBOutlet and another to File's Owner. That must have been how the NSObject was getting returned.
After fixing that, I was getting an assertion failure in -[NSLayoutConstraint constant]. Just on a whim I turned off AutoLayout in the nib, which didn't seem to need it and presto. it works now.