简体   繁体   中英

Transitioning from UISearchDisplayController ==> UISearchController can't get search bar to show

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

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM