search Display Controller is Deprecated in iOS8

12,954

Solution 1

The recipe below worked for me. I just successfully updated multiple scenarios of former iOS 7 code.

Thanks also to the inspiration of Updating to the iOS 8 Search Controller and Apple's API Reference

  1. Remove UISearchDisplayDelegate protocol, add UISearchResultsUpdating and maybe UISearchControllerDelegate instead
@interface YOURTableviewController : UIViewController <UITableViewDelegate, UITableViewDataSource, /*UISearchDisplayDelegate, <- Removed*/ UISearchResultsUpdating /* Added */, UISearchControllerDelegate /* Added */>
{
  1. Add new UISearchController as property:
// New property
@property (nonatomic, strong) UISearchController *searchController;

// ...

@implementation YOURTableviewController

@synthesize searchController; // New property

and initialize the new property in the didLoad method

- (void)viewDidLoad
{
     // New code start -
     self.searchController = [[UISearchController alloc]     initWithSearchResultsController:nil];
     self.searchController.searchResultsUpdater = self;
     self.searchController.delegate = self;
     self.searchController.dimsBackgroundDuringPresentation = NO;

     self.searchController.searchBar.delegate = self;

     self.searchController.searchBar.barTintColor = [UIColor orangeColor];
     [self.tableview setTableHeaderView:self.searchController.searchBar];
     self.definesPresentationContext = YES;
     // - New code end

     // Previous code
     //self.searchDisplayController.searchBar.barTintColor = [UIColor orange]; 

     [super viewDidLoad];
}
  1. Add new UISearchResultsUpdating methods, update UISearchBarDelegate methods, and maybe add helping extra method like below, and maybe also UISearchControllerDelegate methods
#pragma mark -
#pragma mark UISearchResultsUpdating

- (void)updateSearchResultsForSearchController:(UISearchController *)_searchController
{
    NSString *searchString = _searchController.searchBar.text;
    [self searchForText:searchString];
    [self.tableview reloadData];
}

#pragma mark -
#pragma mark UISearchBarDelegate

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    [self updateSearchResultsForSearchController:self.searchController];
}

- (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope
{
    [self updateSearchResultsForSearchController:self.searchController];
}

// Extra method
- (void)searchForText:(NSString *)searchString
{
    /* Put here everything that is in the method:
     - (BOOL)searchDisplayController:(UISearchDisplayController *)controller     shouldReloadTableForSearchString:(NSString *)searchString
     ...BUT WITH NO RETURN VALUE */
}

#pragma mark -
#pragma mark UISearchControllerDelegate

- (void)willPresentSearchController:(UISearchController *)searchController
{
    //..
}
- (void)didPresentSearchController:(UISearchController *)searchController
{
    //..
}
- (void)willDismissSearchController:(UISearchController *)searchController
{
    //..
}
- (void)didDismissSearchController:(UISearchController *)searchController
{
    //..
}
  1. Replace and remove obsolete UISearchDisplayDelegate method(s)
#pragma mark -
#pragma mark UISearchDisplayDelegate

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString 
{ ... }
  1. Replace 'searchDisplayController' everywhere with 'searchController'

  2. Make replacements

Code like:

if (tableView == self.searchDisplayController.searchResultsTableView)

can be replaced with

if (self.searchController.isActive)

Code like:

[self.searchDisplayController setActive:YES];

can be replaced with

[self.searchController setActive:YES];

Solution 2

As UISearchDisplayController is deprecated, you need to use UISearchController for your purpose. Follow this link Using UISearchController

Another link that might be useful for you UISearchController Vs UISearchDisplayController

Solution 3

Yes UISearchDisplay Controller is deprecated, you should use UISearchController instead

Create Search Controller First

@property (strong, nonatomic) UISearchController *searchController;

Initialise Search controller properties

self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.searchController.dimsBackgroundDuringPresentation = NO;

Bind Search controller with your table view

self.tableView.tableHeaderView = self.searchController.searchBar;

Implement UISearchResultUpdating delegate

- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
{
 NSString *searchString = searchController.searchBar.text;
[self searchForText:searchString 
 scope:searchController.searchBar.selectedScopeButtonIndex];
[self.tableView reloadData];
}

You Can also use your filter method to filter result

Your search logic will go here

-(void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope

More detail you can find

http://useyourloaf.com/blog/updating-to-the-ios-8-search-controller/

Share:
12,954
Tunde Dev
Author by

Tunde Dev

Updated on June 23, 2022

Comments

  • Tunde Dev
    Tunde Dev about 2 years

    I am getting the above warning message when trying to run my code.

    NSDictionary *tempDictionary = nil;
    
        if (self.tableView == self.searchDisplayController.searchResultsTableView) {
            tempDictionary = [filteredCompanyArray objectAtIndex:indexPath.row];
        }
        else {
            tempDictionary= [self.client_list objectAtIndex:indexPath.row];
        }
    

    It's been deprecated and did a google search but all I saw were tutorials in Swift.

    I followed Ray Wenderlich tutorial here http://www.raywenderlich.com/16873/how-to-add-search-into-a-table-view but now i'm stuck.

    #pragma mark Content Filtering
    -(void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope {
        // Update the filtered array based on the search text and scope.
        // Remove all objects from the filtered search array
        [self.filteredCompanyArray removeAllObjects];
        // Filter the array using NSPredicate
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.name contains[c] %@",searchText];
        filteredCompanyArray = [NSMutableArray arrayWithArray:[self.client_list filteredArrayUsingPredicate:predicate]];
    }
    
    #pragma mark - UISearchDisplayController Delegate Methods
    -(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
        // Tells the table data source to reload when text changes
        [self filterContentForSearchText:searchString scope:
         [[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]];
        // Return YES to cause the search result table view to be reloaded.
        return YES;
    }
    
    -(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption {
        // Tells the table data source to reload when scope bar selection changes
        [self filterContentForSearchText:self.searchDisplayController.searchBar.text scope:
         [[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:searchOption]];
        // Return YES to cause the search result table view to be reloaded.
        return YES;
    }