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