UISearchController 与 updateSearchResultsForSearchController
UISearchController with updateSearchResultsForSearchController
我找到了如何实现 searchBar,但我不知道在 updateSearchResultsForSearchController 方法中要做什么。我所有的数据都是从 CoreData 中获取的。在这里我把我的代码。如果有人遇到类似问题,请告诉我该怎么做。
@interface PlumbListTableViewController ()<NSFetchedResultsControllerDelegate, UIPageViewControllerDelegate, UISearchBarDelegate, UISearchResultsUpdating, UISearchControllerDelegate>
@property (nonatomic, strong) NSFetchedResultsController *fetchedResultsController;
@property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, strong) NSArray *array;
@property (nonatomic, strong) NSNumber *number;
@property (nonatomic) int sum;
@property (nonatomic, strong) PickerViewController *picker;
@property (nonatomic, strong) UISearchController *searchController;
@property (nonatomic, strong) NSMutableArray *fileteredTableData;
@property (nonatomic, strong) NSArray *products;
@property (nonatomic, strong) NSArray *recipies;
@property (nonatomic, strong) NSArray *searchResults;
@end
@implementation PlumbListTableViewController
-(void)viewDidLoad {
[super viewDidLoad];
//All data from CoreData
self.products = [Product allProducts];
self.searchResults = [NSMutableArray arrayWithCapacity:[self.products count]];
[self.fetchedResultsController performFetch:nil];
CoreDataStack *coreDataStack = [CoreDataStack defaultStack];
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"AddEntry"];
fetchRequest.resultType = NSDictionaryResultType;
self.recipies = [coreDataStack.managedObjectContext executeFetchRequest:fetchRequest error:nil];
}
-(void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:YES];
[self initializeSearchController];
self.tabBarController.tabBar.hidden = NO;
[self showTotalSum];
[self.tableView reloadData];
}
-(void)initializeSearchController {
//instantiate a search results controller for presenting the search/filter results (will be presented on top of the parent table view)
UITableViewController *searchResultsController = [[UITableViewController alloc] initWithStyle:UITableViewStylePlain];
searchResultsController.tableView.dataSource = self;
searchResultsController.tableView.delegate = self;
//instantiate a UISearchController - passing in the search results controller table
self.searchController = [[UISearchController alloc] initWithSearchResultsController:searchResultsController];
//this view controller can be covered by theUISearchController's view (i.e. search/filter table)
self.definesPresentationContext = YES;
//define the frame for the UISearchController's search bar and tint
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.searchController.searchBar.tintColor = [UIColor whiteColor];
//add the UISearchController's search bar to the header of this table
self.tableView.tableHeaderView = self.searchController.searchBar;
//this ViewController will be responsible for implementing UISearchResultsDialog protocol method(s) - so handling what happens when user types into the search bar
self.searchController.searchResultsUpdater = self;
//this ViewController will be responsisble for implementing UISearchBarDelegate protocol methods(s)
self.searchController.searchBar.delegate = self;
}
-(void)updateSearchResultsForSearchController:(UISearchController *)searchController {
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:@"edit"]) {
UITableViewCell *cell = sender;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
UINavigationController *navigationController = segue.destinationViewController;
PlumbAddViewController *entryViewController = (PlumbAddViewController *)navigationController.topViewController;
entryViewController.entry = [self.fetchedResultsController objectAtIndexPath:indexPath];
}
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return self.fetchedResultsController.sections.count;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][section];
return [sectionInfo numberOfObjects];
}
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
ConfigureCellPlumb *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
AddEntry *entry = [self.fetchedResultsController objectAtIndexPath:indexPath];
[cell configureCellforTable:entry];
return cell;
}
-(NSFetchRequest *)entryListFetchRequest {
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"AddEntry"];
fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"date" ascending:NO]];
return fetchRequest;
}
-(NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
CoreDataStack *coreDataStack = [CoreDataStack defaultStack];
NSFetchRequest *fetchRequest = [self entryListFetchRequest];
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:coreDataStack.managedObjectContext sectionNameKeyPath:@"sectionName" cacheName:nil];
_fetchedResultsController.delegate = self;
return _fetchedResultsController;}
根据文档,updateSearchResultsForSearchController: 是 "called when the search bar's text or scope has changed or when the search bar becomes first responder."
因此,您希望在此方法中更新 table 以显示正确的搜索结果。这是我的样子(你的看起来会有所不同,但想法是一样的):
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
{
//make sure model has only results that correspond to the search
[self updateFilteredContentWithSearchText:[self.searchController.searchBar text]];
//update the table now that the model has been updated
[self.specialtySearchResultsTVC.tableView reloadData];
}
//helper method
- (void)updateFilteredContentWithSearchText:(NSString*)searchText
{
[self.specialtySearchResultsTVC.filteredSpecialties removeAllObjects];
for (Specialty *specialty in self.specialties)
{
NSRange nameRange = [specialty.name rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (nameRange.location != NSNotFound)
{
[self.specialtySearchResultsTVC.filteredSpecialties addObject:specialty];
}
}
}
我找到了如何实现 searchBar,但我不知道在 updateSearchResultsForSearchController 方法中要做什么。我所有的数据都是从 CoreData 中获取的。在这里我把我的代码。如果有人遇到类似问题,请告诉我该怎么做。
@interface PlumbListTableViewController ()<NSFetchedResultsControllerDelegate, UIPageViewControllerDelegate, UISearchBarDelegate, UISearchResultsUpdating, UISearchControllerDelegate>
@property (nonatomic, strong) NSFetchedResultsController *fetchedResultsController;
@property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, strong) NSArray *array;
@property (nonatomic, strong) NSNumber *number;
@property (nonatomic) int sum;
@property (nonatomic, strong) PickerViewController *picker;
@property (nonatomic, strong) UISearchController *searchController;
@property (nonatomic, strong) NSMutableArray *fileteredTableData;
@property (nonatomic, strong) NSArray *products;
@property (nonatomic, strong) NSArray *recipies;
@property (nonatomic, strong) NSArray *searchResults;
@end
@implementation PlumbListTableViewController
-(void)viewDidLoad {
[super viewDidLoad];
//All data from CoreData
self.products = [Product allProducts];
self.searchResults = [NSMutableArray arrayWithCapacity:[self.products count]];
[self.fetchedResultsController performFetch:nil];
CoreDataStack *coreDataStack = [CoreDataStack defaultStack];
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"AddEntry"];
fetchRequest.resultType = NSDictionaryResultType;
self.recipies = [coreDataStack.managedObjectContext executeFetchRequest:fetchRequest error:nil];
}
-(void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:YES];
[self initializeSearchController];
self.tabBarController.tabBar.hidden = NO;
[self showTotalSum];
[self.tableView reloadData];
}
-(void)initializeSearchController {
//instantiate a search results controller for presenting the search/filter results (will be presented on top of the parent table view)
UITableViewController *searchResultsController = [[UITableViewController alloc] initWithStyle:UITableViewStylePlain];
searchResultsController.tableView.dataSource = self;
searchResultsController.tableView.delegate = self;
//instantiate a UISearchController - passing in the search results controller table
self.searchController = [[UISearchController alloc] initWithSearchResultsController:searchResultsController];
//this view controller can be covered by theUISearchController's view (i.e. search/filter table)
self.definesPresentationContext = YES;
//define the frame for the UISearchController's search bar and tint
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.searchController.searchBar.tintColor = [UIColor whiteColor];
//add the UISearchController's search bar to the header of this table
self.tableView.tableHeaderView = self.searchController.searchBar;
//this ViewController will be responsible for implementing UISearchResultsDialog protocol method(s) - so handling what happens when user types into the search bar
self.searchController.searchResultsUpdater = self;
//this ViewController will be responsisble for implementing UISearchBarDelegate protocol methods(s)
self.searchController.searchBar.delegate = self;
}
-(void)updateSearchResultsForSearchController:(UISearchController *)searchController {
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:@"edit"]) {
UITableViewCell *cell = sender;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
UINavigationController *navigationController = segue.destinationViewController;
PlumbAddViewController *entryViewController = (PlumbAddViewController *)navigationController.topViewController;
entryViewController.entry = [self.fetchedResultsController objectAtIndexPath:indexPath];
}
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return self.fetchedResultsController.sections.count;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][section];
return [sectionInfo numberOfObjects];
}
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
ConfigureCellPlumb *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
AddEntry *entry = [self.fetchedResultsController objectAtIndexPath:indexPath];
[cell configureCellforTable:entry];
return cell;
}
-(NSFetchRequest *)entryListFetchRequest {
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"AddEntry"];
fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"date" ascending:NO]];
return fetchRequest;
}
-(NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
CoreDataStack *coreDataStack = [CoreDataStack defaultStack];
NSFetchRequest *fetchRequest = [self entryListFetchRequest];
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:coreDataStack.managedObjectContext sectionNameKeyPath:@"sectionName" cacheName:nil];
_fetchedResultsController.delegate = self;
return _fetchedResultsController;}
根据文档,updateSearchResultsForSearchController: 是 "called when the search bar's text or scope has changed or when the search bar becomes first responder."
因此,您希望在此方法中更新 table 以显示正确的搜索结果。这是我的样子(你的看起来会有所不同,但想法是一样的):
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
{
//make sure model has only results that correspond to the search
[self updateFilteredContentWithSearchText:[self.searchController.searchBar text]];
//update the table now that the model has been updated
[self.specialtySearchResultsTVC.tableView reloadData];
}
//helper method
- (void)updateFilteredContentWithSearchText:(NSString*)searchText
{
[self.specialtySearchResultsTVC.filteredSpecialties removeAllObjects];
for (Specialty *specialty in self.specialties)
{
NSRange nameRange = [specialty.name rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (nameRange.location != NSNotFound)
{
[self.specialtySearchResultsTVC.filteredSpecialties addObject:specialty];
}
}
}