UISplitViewController 使用 UISearchController 在搜索时不将对象传递给 detailView
UISplitViewController using a UISearchController not passing objects to detailView while searching
我创建了一个主从应用程序,我为表视图实现了一个 UISearchController。
当搜索为空时,TableView 和 detailViews 工作正常,但当搜索时,tableview 显示正确筛选的对象但无法将其传递给 detailView。
如有任何帮助,我们将不胜感激。提前致谢。
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [[self.fetchedResultsController sections] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
// Display the First Letter of the person's last name as section headings.
//return [[[fetchedResultsController sections] objectAtIndex:section] name];
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
return [NSString stringWithFormat:@"%@", [sectionInfo name]];
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
if (index == 0) {
// search item
[tableView scrollRectToVisible:[[tableView tableHeaderView] bounds] animated:NO];
return -1;
}
return index-1;
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
// Return the array of section index titles
NSArray *searchArray = [NSArray arrayWithObject:UITableViewIndexSearch];
return [searchArray arrayByAddingObjectsFromArray:self.fetchedResultsController.sectionIndexTitles];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//self.navigationItem.leftBarButtonItem = self.editButtonItem;
//UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)];
//self.navigationItem.rightBarButtonItem = addButton;
self.detailViewController = (DetailViewController *)[[self.splitViewController.viewControllers lastObject] topViewController];
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Printers" style:UIBarButtonItemStylePlain target:nil action:nil];
//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;
}
#pragma mark - UISearchResultsUpdating
-(void)updateSearchResultsForSearchController:(UISearchController *)searchController {
//get search text from user input
[NSFetchedResultsController deleteCacheWithName:@"Master"];
// Init a fetch request
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
// Apply an ascending sort for the color items
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"printer" ascending:YES selector:@selector(caseInsensitiveCompare:)];
NSArray *descriptors = [NSArray arrayWithObject:sortDescriptor];
[fetchRequest setSortDescriptors:descriptors];
// Recover query
query = self.searchController.searchBar.text;
if (query && query.length) fetchRequest.predicate = [NSPredicate predicateWithFormat:@"(printer contains[cd] %@)",query];
// Init the fetched results controller
NSError *error;
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"fLetter" cacheName:@"Master"];
self.fetchedResultsController.delegate = self;
if (![[self fetchedResultsController] performFetch:&error]) NSLog(@"Error: %@", [error localizedDescription]);
//now that the tableSections and tableSectionsAndItems properties are updated, reload the UISearchController's tableview
[((UITableViewController *)self.searchController.searchResultsController).tableView reloadData];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"showDetail"])
{
NSLog(@"showDetail segue was called...");
if ([self.searchController.searchBar.text isEqualToString:@""])
{
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
Event *object = [[self fetchedResultsController] objectAtIndexPath:indexPath];
DetailViewController *controller = (DetailViewController *)[[segue destinationViewController] topViewController];
[controller setDetailItem:object];
controller.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem;
controller.navigationItem.leftItemsSupplementBackButton = YES;
NSLog(@"Search Predicate was blank, and the code came here...");
}
else
{
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
Event *object = [self.fetchedResultsController.fetchedObjects filteredArrayUsingPredicate:self.searchPredicate][indexPath.row];
DetailViewController *controller = (DetailViewController *)[[segue destinationViewController] topViewController];
[controller setDetailItem:object];
controller.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem;
controller.navigationItem.leftItemsSupplementBackButton = YES;
NSLog(@"Searching: section %ld row %ld", (long)indexPath.section, (long)indexPath.row);
NSLog(@"searchPredicate %@", self.searchPredicate); }
[self.searchController.searchBar setText:@""];
}
}
NSIndexPath *indexPath = [self.fetchedResultsController.fetchedObjects filteredArrayUsingPredicate:self.searchPredicate][indexPath.row];
我很确定问题出在这一行。我在上面一行中提到的最正确的 indexPath 在哪里?
当您从 tableView 中搜索和选择时,tableView 总是 return 选定的行,因此请使用
NSIndexPath *indexPath = [self.searchDisplayController.searchResultsTableView indexPathForSelectedRow];
而不是
NSIndexPath *indexPath = [self.fetchedResultsController.fetchedObjects filteredArrayUsingPredicate:self.searchPredicate][indexPath.row];
我创建了一个主从应用程序,我为表视图实现了一个 UISearchController。
当搜索为空时,TableView 和 detailViews 工作正常,但当搜索时,tableview 显示正确筛选的对象但无法将其传递给 detailView。
如有任何帮助,我们将不胜感激。提前致谢。
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [[self.fetchedResultsController sections] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
// Display the First Letter of the person's last name as section headings.
//return [[[fetchedResultsController sections] objectAtIndex:section] name];
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
return [NSString stringWithFormat:@"%@", [sectionInfo name]];
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
if (index == 0) {
// search item
[tableView scrollRectToVisible:[[tableView tableHeaderView] bounds] animated:NO];
return -1;
}
return index-1;
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
// Return the array of section index titles
NSArray *searchArray = [NSArray arrayWithObject:UITableViewIndexSearch];
return [searchArray arrayByAddingObjectsFromArray:self.fetchedResultsController.sectionIndexTitles];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//self.navigationItem.leftBarButtonItem = self.editButtonItem;
//UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)];
//self.navigationItem.rightBarButtonItem = addButton;
self.detailViewController = (DetailViewController *)[[self.splitViewController.viewControllers lastObject] topViewController];
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Printers" style:UIBarButtonItemStylePlain target:nil action:nil];
//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;
}
#pragma mark - UISearchResultsUpdating
-(void)updateSearchResultsForSearchController:(UISearchController *)searchController {
//get search text from user input
[NSFetchedResultsController deleteCacheWithName:@"Master"];
// Init a fetch request
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
// Apply an ascending sort for the color items
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"printer" ascending:YES selector:@selector(caseInsensitiveCompare:)];
NSArray *descriptors = [NSArray arrayWithObject:sortDescriptor];
[fetchRequest setSortDescriptors:descriptors];
// Recover query
query = self.searchController.searchBar.text;
if (query && query.length) fetchRequest.predicate = [NSPredicate predicateWithFormat:@"(printer contains[cd] %@)",query];
// Init the fetched results controller
NSError *error;
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"fLetter" cacheName:@"Master"];
self.fetchedResultsController.delegate = self;
if (![[self fetchedResultsController] performFetch:&error]) NSLog(@"Error: %@", [error localizedDescription]);
//now that the tableSections and tableSectionsAndItems properties are updated, reload the UISearchController's tableview
[((UITableViewController *)self.searchController.searchResultsController).tableView reloadData];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"showDetail"])
{
NSLog(@"showDetail segue was called...");
if ([self.searchController.searchBar.text isEqualToString:@""])
{
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
Event *object = [[self fetchedResultsController] objectAtIndexPath:indexPath];
DetailViewController *controller = (DetailViewController *)[[segue destinationViewController] topViewController];
[controller setDetailItem:object];
controller.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem;
controller.navigationItem.leftItemsSupplementBackButton = YES;
NSLog(@"Search Predicate was blank, and the code came here...");
}
else
{
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
Event *object = [self.fetchedResultsController.fetchedObjects filteredArrayUsingPredicate:self.searchPredicate][indexPath.row];
DetailViewController *controller = (DetailViewController *)[[segue destinationViewController] topViewController];
[controller setDetailItem:object];
controller.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem;
controller.navigationItem.leftItemsSupplementBackButton = YES;
NSLog(@"Searching: section %ld row %ld", (long)indexPath.section, (long)indexPath.row);
NSLog(@"searchPredicate %@", self.searchPredicate); }
[self.searchController.searchBar setText:@""];
}
}
NSIndexPath *indexPath = [self.fetchedResultsController.fetchedObjects filteredArrayUsingPredicate:self.searchPredicate][indexPath.row];
我很确定问题出在这一行。我在上面一行中提到的最正确的 indexPath 在哪里?
当您从 tableView 中搜索和选择时,tableView 总是 return 选定的行,因此请使用
NSIndexPath *indexPath = [self.searchDisplayController.searchResultsTableView indexPathForSelectedRow];
而不是
NSIndexPath *indexPath = [self.fetchedResultsController.fetchedObjects filteredArrayUsingPredicate:self.searchPredicate][indexPath.row];