Reputation: 3137
I have an app that was written for iOS 7 the I need to update as UISearchDisplayController is deprecated for UISearchController.
I have went through several tutorials and tried but I cannot get this to work, however I am close.
I am following this pattern.
The problem I am running into is that the pattern I am following loads the data from a son file into an NSDict object, but my data is in an Array. No problem, I just modified the search to use a predicate (I hard coded something for now, get all records with an E in the name).
But I am getting the following error:
2017-09-12 13:01:41.538 Scoular[7644:1963822] -[employee isEqualToString:]: unrecognized selector sent to instance 0x608000105580 2017-09-12 13:01:41.604 Scoular[7644:1963822] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[employee isEqualToString:]: unrecognized selector sent to instance 0x608000105580'
In the SearchResultsTableViewController.m file, at the line
cell.textLabel.text = self.searchResults[indexPath.row];
from the m file below. I am stumped. Any help would be greatly appreciated.
#import "SearchResultsTableViewController.h"
@interface SearchResultsTableViewController ()
@property (nonatomic, strong) NSArray *array;
@end
@implementation SearchResultsTableViewController
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.searchResults count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SearchResultCell" forIndexPath:indexPath];
cell.textLabel.text = self.searchResults[indexPath.row];
return cell;
}
@end
Header File
@import UIKit;
@class EmployeeDetailViewController;
#import <CoreData/CoreData.h>
#import "EmployeeDatabase.h"
@interface EmployeeListViewController : UITableViewController
@end
Implementation File
#import "EmployeeListViewController.h"
#import "EmployeeDetailViewController.h"
#import "SearchResultsTableViewController.h"
@interface EmployeeListViewController () <UISearchResultsUpdating>
@property (nonatomic, strong) NSMutableArray *employees;
@property (nonatomic, strong) UISearchController *searchController;
@property (nonatomic, strong) NSMutableArray *searchResults;
@property (nonatomic,retain) NSMutableDictionary *sections;
@end
@implementation EmployeeListViewController
BOOL isSearching;
//Do I still need this
- (void)awakeFromNib {
if ([[UIDevice currentDevice] userInterfaceIdiom] ==
UIUserInterfaceIdiomPad) {
self.clearsSelectionOnViewWillAppear = NO;
self.preferredContentSize = CGSizeMake(320.0, 600.0);
}
[super awakeFromNib];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Get array of employees and sections
self.employees = [EmployeeDatabase getEmployees];
self.sections = [EmployeeDatabase getSections:_employees];
// There's no transition in our storyboard to our search results tableview or navigation controller
// so we'll have to grab it using the instantiateViewControllerWithIdentifier: method
UINavigationController *searchResultsController = [[self storyboard] instantiateViewControllerWithIdentifier:@"TableSearchResultsNavController"];
// Our instance of UISearchController will use searchResults
self.searchController = [[UISearchController alloc] initWithSearchResultsController:searchResultsController];
// The searchcontroller's searchResultsUpdater property will contain our tableView.
self.searchController.searchResultsUpdater = self;
// The searchBar contained in XCode's storyboard is a leftover from UISearchDisplayController.
// Don't use this. Instead, we'll create the searchBar programatically.
self.searchController.searchBar.frame = CGRectMake(self.searchController.searchBar.frame.origin.x,
self.searchController.searchBar.frame.origin.y,
self.searchController.searchBar.frame.size.width, 44.0);
self.tableView.tableHeaderView = self.searchController.searchBar;
// Set the back bar button
UIBarButtonItem *backButton =
[[UIBarButtonItem alloc] initWithTitle:@"Employees"
style:UIBarButtonItemStylePlain
target:nil
action:nil];
self.navigationItem.backBarButtonItem = backButton;
}
#pragma mark - Table Sections
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSInteger tmpCount;
if (isSearching) {
tmpCount = 1;
} else {
tmpCount = [[self.sections allKeys] count];
}
return tmpCount;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.employees count];
}
#pragma mark - Table View
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
}
employee *thisEmployee =
[[self.sections
valueForKey:[[[self.sections allKeys]
sortedArrayUsingSelector:
@selector(localizedCaseInsensitiveCompare:)]
objectAtIndex:indexPath.section]]
objectAtIndex:indexPath.row];
cell.textLabel.text = thisEmployee.fulNme;
return cell;
}
- (NSString *)tableView:(UITableView *)tableView
titleForHeaderInSection:(NSInteger)section {
NSString *tmpString;
//if (tableView == self.searchDisplayController.searchResultsTableView) {
//tmpString = nil;
//} else {
tmpString =
[[[self.sections allKeys]
sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:
)] objectAtIndex:section];
//}
return tmpString;
}
#pragma mark - Right side bar alphabetical index
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
NSArray *tmpTitle;
if (isSearching) {
tmpTitle = nil;
} else {
tmpTitle = [[self.sections allKeys]
sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
}
return tmpTitle;
}
#pragma mark - UISearchControllerDelegate & UISearchResultsDelegate
// Called when the search bar becomes first responder
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
{
// Set searchString equal to what's typed into the searchbar
NSString *searchString = self.searchController.searchBar.text;
[self updateFilteredContentForAirlineName:searchString];
// If searchResultsController
if (self.searchController.searchResultsController) {
UINavigationController *navController = (UINavigationController *)self.searchController.searchResultsController;
// Present SearchResultsTableViewController as the topViewController
SearchResultsTableViewController *vc = (SearchResultsTableViewController *)navController.topViewController;
// Update searchResults
vc.searchResults = self.searchResults;
// And reload the tableView with the new data
[vc.tableView reloadData];
}
}
// Update self.searchResults based on searchString, which is the argument in passed to this method
- (void)updateFilteredContentForAirlineName:(NSString *)employeeName
{
if (employeeName == nil) {
// If empty the search results are the same as the original data
self.searchResults = [self.employees mutableCopy];
} else {
NSArray *searchResults2 = [[NSMutableArray alloc] init];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"fulNme contains 'E'"];
searchResults2 = [self.employees filteredArrayUsingPredicate:predicate];
self.searchResults = [searchResults2 mutableCopy];
}
}
@end
Upvotes: 0
Views: 374
Reputation: 1091
In your updateFilteredContentForAirlineName
function you are searching from self.employees
array which probably contains employee
custom class object. For that reason your self.searchResults
array also containing same class object.
But in your cellForRowAtIndexPath
of SearchResultsTableViewController
your are doing cell.textLabel.text = self.searchResults[indexPath.row];
that means you are adding employee
object as string in cell.textLabel
which causing your app to crash. Instead you can try this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SearchResultCell" forIndexPath:indexPath];
employee *thisEmployee = self.searchResults[indexPath.row];
cell.textLabel.text = thisEmployee.fulNme;
return cell;
}
Upvotes: 1