3

J'ai un problème étrange lors de la recherche d'un UITableView en utilisant un UISearchDisplayController. UITableViewController est une sous-classe d'un autre UITableViewController avec une méthode working DidSelectRowAtIndexPath. Sans effectuer de recherches, le contrôleur gère correctement les sélections, envoyant à la superclasse un appel à didSelectRowAtIndexPath, mais si je sélectionne une cellule lors d'une recherche, la superclasse ne reçoit rien mais la cellule est mise en surbrillance. Voici le code de ma sous-classe.Pourquoi mon UISearchDisplayController ne lance-t-il pas la méthode didSelectRowAtIndexPath?

@implementation AdvancedViewController 


@synthesize searchDisplayController, dict, filteredList; 


- (void)viewDidLoad { 
    [super viewDidLoad]; 

    // Programmatically set up search bar 
    UISearchBar *mySearchBar = [[UISearchBar alloc] init]; 
    mySearchBar.delegate = self; 
    [mySearchBar setAutocapitalizationType:UITextAutocapitalizationTypeNone]; 
    [mySearchBar sizeToFit]; 
    self.tableView.tableHeaderView = mySearchBar; 

    // Programmatically set up search display controller 
    searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:mySearchBar contentsController:self]; 
    [self setSearchDisplayController:searchDisplayController]; 
    [searchDisplayController setDelegate:self]; 
    [searchDisplayController setSearchResultsDataSource:self]; 

    // Parse data from server 
    NSData * jsonData = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]]; 
    NSArray * items = [[NSArray alloc] initWithArray:[[CJSONDeserializer deserializer] deserializeAsArray:jsonData error:nil]]; 

    // Init variables 
    dict = [[NSMutableDictionary alloc] init]; 
    listIndex = [[NSMutableArray alloc] init]; 
    fullList = [[NSMutableArray alloc] init]; 
    filteredList = [[NSMutableArray alloc] init]; 

    // Get each item and format it for the UI 
    for(NSMutableArray * item in items) { 
     // Get the first letter 
     NSString * firstKey = [[[item objectAtIndex:0] substringWithRange:NSMakeRange(0,1)] uppercaseString]; 

     // Put symbols and numbers in the same section 
     if ([[firstKey stringByTrimmingCharactersInSet:[[NSCharacterSet letterCharacterSet] invertedSet]] isEqualToString:@""]) firstKey = @"#"; 

     // If there isn't a section with this key 
     if (![listIndex containsObject:firstKey]) { 
      // Add the key to the index for faster access (because it's already sorted) 
      [listIndex addObject:firstKey]; 
      // Add the key to the unordered dictionary 
      [dict setObject:[NSMutableArray array] forKey:firstKey]; 
     } 
     // Add the object to the dictionary 
     [[dict objectForKey:firstKey] addObject:[[NSMutableDictionary alloc] initWithObjects:item forKeys:[NSArray arrayWithObjects:@"name", @"url", nil]]]; 
     // Add the object to the list for simple searching 
     [fullList addObject:[[NSMutableDictionary alloc] initWithObjects:item forKeys:[NSArray arrayWithObjects:@"name", @"url", nil]]]; 
    } 

    filteredList = [NSMutableArray arrayWithCapacity:[fullList count]]; 
} 


#pragma mark - 
#pragma mark Table view data source 

// Custom method for object oriented data access 
- (NSString *)tableView:(UITableView *)tableView dataForRowAtIndexPath:(NSIndexPath *)indexPath withKey:(NSString *)key { 
    return (NSString *)((tableView == self.searchDisplayController.searchResultsTableView) ? 
         [[filteredList objectAtIndex:indexPath.row] objectForKey:key] : 
         [[[dict objectForKey:[listIndex objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row] valueForKey:key]); 
} 

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
    return (tableView == self.searchDisplayController.searchResultsTableView) ? 1 : (([listIndex count] > 0) ? [[dict allKeys] count] : 1); 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    return (tableView == self.searchDisplayController.searchResultsTableView) ? [filteredList count] : [[dict objectForKey:[listIndex objectAtIndex:section]] count]; 
} 

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { 
    return (tableView == self.searchDisplayController.searchResultsTableView) ? [[NSArray alloc] initWithObjects:nil] : listIndex; 
} 

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 
    return (tableView == self.searchDisplayController.searchResultsTableView) ? @"" : [listIndex objectAtIndex:section]; 
} 


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    static NSString *kCellID = @"cellID"; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellID]; 
    if (cell == nil) { 
     cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellID] autorelease]; 
     cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 
    } 

    NSString * name = nil; 

    // TODO: Make dataForRowAtIndexPath work here 
    if (tableView == self.searchDisplayController.searchResultsTableView) { 
     // NOTE: dataForRowAtIndexPath causes this to crash for some unknown reason. Maybe it is called before viewDidLoad and has no data? 
     name = [[filteredList objectAtIndex:indexPath.row] objectForKey:@"name"]; 
    } else { 
     // This always works 
     name = [self tableView:[self tableView] dataForRowAtIndexPath:indexPath withKey:@"name"]; 
    } 

    cell.textLabel.text = name; 

    return cell; 
} 


#pragma mark Search Methods 


- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope { 
    // Clear the filtered array 
    [self.filteredList removeAllObjects]; 

    // Filter the array 
    for (NSDictionary *item in fullList) { 
     // Compare the item's name to the search text 
     NSComparisonResult result = [[item objectForKey:@"name"] compare:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [searchText length])]; 
     if (result == NSOrderedSame) { 
      // Add to the filtered array if it matches 
      [self.filteredList addObject:item]; 
     } 
    } 
} 


- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString { 
    [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; 
} 


- (void)viewDidUnload { filteredList = nil; } 


@end 
+0

Appelez-moi fou, mais je ne peux pas trouver votre méthode didSelectRowAtIndexPath dans cet échantillon de code ...? –

Répondre

0

Mon conseil est de garder une propriété UITableView dans votre contrôleur de vue appelé currentTableView. Lorsque le texte change de champ de recherche, nous avons mis la valeur de cette propriété:

- (BOOL) searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString searchScope:(NSInteger)searchOption { 
    ... 
    if ([[searchString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length]) 
     self.currentTableView = searchDisplayController.searchResultsTableView; 
    else 
     self.currentTableView = tableView; 
    ... 
} 

Toutes les autres méthodes peuvent tester si currentTableView est une vue de tableau de résultats de recherche ou d'une vue de la table « normale ». Le contrôleur de résultats récupéré peut fonctionner avec currentTableView quel que soit le contexte dans lequel il se trouve. Etc.

+0

qui a fonctionné! Merci! : D – MadMod

19

Même problème qui m'est arrivé, j'ai fait la même erreur avec vous. J'ai oublié d'ajouter searchResultsDelegate. Mon problème est résolu en changeant le code comme ci-dessous:

ajouter

[searchDisplayController setSearchResultsDelegate:self]; 

ci-dessous

[searchDisplayController setDelegate:self]; 
[searchDisplayController setSearchResultsDataSource:self]; 
+3

+1 cela a fonctionné sur l'autre réponse –