3

У меня возникла странная проблема при поиске UITableView с помощью UISearchDisplayController. UITableViewController является подклассом другого UITableViewController с рабочим методом didSelectRowAtIndexPath. Без поиска контроллер отлично обрабатывает выделение, отправляя суперкласс на вызов didSelectRowAtIndexPath, но если я выбираю ячейку при поиске суперкласса, получает ничего, кроме ячейки подсвечивается. Ниже приведен код из моего подкласса.Почему мой UISearchDisplayController не запускает метод 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

Позови меня с ума, но я не могу найти свой метод didSelectRowAtIndexPath в этом примере кода ...? –

ответ

0

Мой совет держать UITableView свойство в контроллере представления под названием currentTableView. При изменении текста поиска поля, мы устанавливаем значение этого свойства,:

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

Все другие методы могут проверить, является ли currentTableView поиск просмотр результатов таблицы или «нормальный» вид таблицы. Контроллер получаемых результатов может работать с currentTableView независимо от того, в каком контексте он находится. И т.д.

+0

, который сработал! благодаря! : D – MadMod

19

Такая же проблема со мной, я сделал с вами такую ​​же ошибку. Забыл добавить searchResultsDelegate. Моя проблема решается путем изменения кода, как показано ниже:

добавить

[searchDisplayController setSearchResultsDelegate:self]; 

ниже

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

+1 это работало над другим ответом –

Смежные вопросы