I have been trying to implement UISearchController
by following stackoverflow thread:
How to implement UISearchController with objective c
and Apples's documentation, but can't make it working. When the initial controller (EVTSearchViewController
which is defined as UIViewController
) that complies with UISearchBarDelegate, UISearchControllerDelegate, UISearchResultsUpdating, UITableViewDelegate
(I needed to make it compliant with UITableViewDelegate
too, since I am making it a delegate of the other UITableViewController
type EVTSearchResultsViewController *resultsController
s tableView) delegates is presented, I see my .xib
with the UISearchBar
and UITableView
, I click the search bar and start typing:
When I type one letter, search bar disappears and nothing is shown:
First, I do not want the search bar to disappear. Second, updateSearchResultsForSearchController
seems not to be called at all since NSLog()
set up there does not produce any output when I am typing in the search bar.
I have .xib
for the EVTSearchViewController
and it has a UISearchBar
that I am connecting to the respective property: IBOutlet UISearchBar *searchBar
which is then made to point to the UISearchControllers' searchBar:
self.searchBar = self.searchController.searchBar
There is also UITableView
that I put below the UISearchBar
in the .xib
. Another controller that I am using inside EVTSearchViewController
is EVTSearchResultsViewController
, it is UITableViewController
and it does not have its .xib
.
Below is the code for viewDidLoad
and updateSearchResultsForSearchController
methods:
- (void)viewDidLoad
{
_resultsController = [[EVTSearchResultsViewController alloc] init];
_searchController = [[UISearchController alloc] initWithSearchResultsController:_resultsController];
self.searchController.searchResultsUpdater = self;
self.searchController.searchBar.placeholder = nil;
[self.searchController.searchBar sizeToFit];
self.searchBar = self.searchController.searchBar;
// we want to be the delegate for our filtered table so didSelectRowAtIndexPath is called for both tables
self.resultsController.tableView.delegate = self;
self.searchController.delegate = self;
self.searchController.dimsBackgroundDuringPresentation = YES; // default is YES
self.searchController.searchBar.delegate = self; // so we can monitor text changes + others
// Search is now just presenting a view controller. As such, normal view controller
// presentation semantics apply. Namely that presentation will walk up the view controller
// hierarchy until it finds the root view controller or one that defines a presentation context.
//
self.definesPresentationContext = YES; // know where you want UISearchController to be displayed
}
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
// update the filtered array based on the search text
NSString *searchText = searchController.searchBar.text;
NSLog(@"searchText: %@", searchText);
if (searchText == nil) {
// If empty the search results are the same as the original data
self.searchResults = [[[EVTItemStore sharedStore] allItems] mutableCopy];
} else {
NSMutableArray *searchResults = [[NSMutableArray alloc] init];
NSArray *allEvents = [[EVTItemStore sharedStore] allItems];
NSLog(@"allEvents: %@", allEvents);
for (EVTItem *event in allEvents) {
/*if ([event.number containsString:searchText] || [[phoneMO.closrr_id filteredId] containsString:searchText] || [[phoneMO.contact.fullname lowercaseString] containsString:[searchText lowercaseString]]) {
[searchResults addObject:phoneMO];
}*/
if ([event.eventName containsString:searchText]) {
[searchResults addObject:event];
}
}
self.searchResults = searchResults;
}
// hand over the filtered results to our search results table
EVTSearchResultsViewController *resultsController = (EVTSearchResultsViewController *)self.searchController.searchResultsController;
resultsController.filteredEvents = self.searchResults;
[resultsController.tableView reloadData];
}
The respective @properties
defined in EVTSearchViewController
:
@interface EVTSearchViewController ()
@property (weak, nonatomic) IBOutlet UISearchBar *searchBar;
@property (nonatomic, strong) UISearchController *searchController;
@property (nonatomic, strong) EVTSearchResultsViewController *resultsController;
@property (nonatomic, strong) NSMutableArray *searchResults;
// For state restoration
@property BOOL searchControllerWasActive;
@property BOOL searchControllerSearchFieldWasFirstResponder;
@end
Then, here is the code for EVTSearchResultsViewController
:
#import "EVTSearchResultsViewController.h"
@implementation EVTSearchResultsViewController
- (instancetype)init
{
// Call the superclass's designated initializer
self = [super initWithStyle:UITableViewStylePlain];
if (self) {
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerClass:[UITableViewCell class]
forCellReuseIdentifier:@"UISearchViewCell"];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return [self.filteredEvents count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:@"UISearchViewCell"
forIndexPath:indexPath];
cell.textLabel.text = self.filteredEvents[indexPath.row];
return cell;
}
@end
The methods of EVTSearchResultsViewController
above are not called at all which makes look very strange for me, why do we need it at all, then?
I tried to set UISearchBar
the way Apple docs recommend:
self.resultsTableView.tableHeaderView = self.searchController.searchBar;
but it gives me a non-responsive search box, so when pressing nothing happens.
Could anyone, please, help with resolving the question. The other question linked above can also be clarified then. Thank you.