2013-11-23 2 views
1

Я пишу приложение iOS (обновленное приложение из учебника iOS). Он имеет представление с UITableView и UISearchBar (спасибо Ayan и Tommy). Теперь моя проблема следующая: в таблице показаны все записи из основного объекта данных, когда я нажимаю на ячейку, приложение показывает подробный вид из выбранной ячейки. Это прекрасно работает. Проблема в том, что после использования метода поиска, если я нажимаю на ячейку результата поиска, приложение не отображает подробный вид из выбранной ячейки. Я предполагаю, что я должен определить где-нибудь отправителя поиска, но не знаю, как и где его включить. Это мой код в данный момент, и любая помощь или подсказка приветствуется ... СпасибоПриложение iOS с функцией просмотра таблицы и поиска

#import "PersonsTVC.h" 
#import "Person.h" 

@implementation PersonsTVC 
@synthesize fetchedResultsController = __fetchedResultsController; 
@synthesize managedObjectContext = __managedObjectContext; 
@synthesize selectedPerson; 
@synthesize searchResults; 

- (void)setupFetchedResultsController 
{ 

    NSString *entityName = @"Person"; 
    NSLog(@"Setting up a Fetched Results Controller for the Entity named %@", entityName); 


    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:entityName]; 

    request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"firstname" 
                        ascending:YES 
                         selector:@selector(localizedCaseInsensitiveCompare:)]]; 

    self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request 
                     managedObjectContext:self.managedObjectContext 
                      sectionNameKeyPath:nil 
                        cacheName:nil]; 
    [self performFetch]; 
} 



- (void) viewDidLoad 
{ 
    self.searchResults = [NSMutableArray arrayWithCapacity:[[self.fetchedResultsController fetchedObjects] count]]; 
    [self.tableView reloadData]; 
} 
-(void) viewDidUnload{ 
    self.searchResults = nil; 
} 



- (void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
    [self setupFetchedResultsController]; 
} 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"Persons Cell"; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 
    } 

    // Configure the cell... 
    // Configure the cell... 
    Person *person = nil; 

    if (tableView == self.searchDisplayController.searchResultsTableView) 
    { 
     NSLog(@"Configuring cell to show search results"); 
     person = [self.searchResults objectAtIndex:indexPath.row]; 
    } 
    else 
    { 
     NSLog(@"Configuring cell to show normal data"); 
     person = [self.fetchedResultsController objectAtIndexPath:indexPath]; 
    } 








    NSString *fullname = [NSString stringWithFormat:@"%@ %@", person.firstname, person.surname]; 
    cell.textLabel.text = person.firstname; 
    if ([person.inRole.color isEqual :@"Yellow"]) 
    { 
     cell.imageView.image = [UIImage imageNamed:@"Yellow"]; 
    } 
    if ([person.inRole.color isEqual :@"Black"]) 
    { 
     cell.imageView.image = [UIImage imageNamed:@"Black"]; 
    } 
    if ([person.inRole.color isEqual :@"Grey"]) 
    { 
     cell.imageView.image = [UIImage imageNamed:@"Grey"]; 
    } 
    if ([person.inRole.color isEqual :@"Red"]) 
    { 
     cell.imageView.image = [UIImage imageNamed:@"Red"]; 
    } 
    if ([person.inRole.color isEqual :@"Blue"]) 
    { 
     cell.imageView.image = [UIImage imageNamed:@"Blue"]; 
    } 
    if ([person.inRole.color isEqual :@"Dark Green"]) 
    { 
     cell.imageView.image = [UIImage imageNamed:@"DarkGreen"]; 
    } 
    if ([person.inRole.color isEqual :@"Light Green"]) 
    { 
     cell.imageView.image = [UIImage imageNamed:@"LightGreen"]; 
    } 
    if ([person.inRole.color isEqual :@"Light Blue"]) 
    { 
     cell.imageView.image = [UIImage imageNamed:@"LightBlue"]; 
    } 
    if ([person.inRole.color isEqual :@"Brown"]) 
    { 
     cell.imageView.image = [UIImage imageNamed:@"Brown"]; 
    } 
    if ([person.inRole.color isEqual :@"Dark Orange"]) 
    { 
     cell.imageView.image = [UIImage imageNamed:@"DarkOrange"]; 
    } 
    cell.detailTextLabel.text = person.surname; 
    //cell.textLabel.text = person.firstname; 
    return cell; 
} 


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    if (tableView == self.searchDisplayController.searchResultsTableView) 
    { 
     return [self.searchResults count]; 
    } 
    else 
    { 
     return [[[self.fetchedResultsController sections] objectAtIndex:section] numberOfObjects]; 
    } 
} 


- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 

    if (editingStyle == UITableViewCellEditingStyleDelete) { 

     [self.tableView beginUpdates]; // Avoid NSInternalInconsistencyException 

     // Delete the person object that was swiped 
     Person *personToDelete = [self.fetchedResultsController objectAtIndexPath:indexPath]; 
     NSLog(@"Deleting (%@)", personToDelete.firstname); 
     [self.managedObjectContext deleteObject:personToDelete]; 
     [self.managedObjectContext save:nil]; 

     // Delete the (now empty) row on the table 
     [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
     [self performFetch]; 

     [self.tableView endUpdates]; 
    } 
} 

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
    if ([segue.identifier isEqualToString:@"Add Person Segue"]) 
    { 
     NSLog(@"Setting PersonsTVC as a delegate of PersonDetailTVC"); 
     PersonDetailTVC *personDetailTVC = segue.destinationViewController; 
     personDetailTVC.delegate = self; 

     NSLog(@"Creating a new person and passing it to PersonDetailTVC"); 
     Person *newPerson = [NSEntityDescription insertNewObjectForEntityForName:@"Person" 
                  inManagedObjectContext:self.managedObjectContext]; 

     personDetailTVC.person = newPerson; 
    } 
    else if ([segue.identifier isEqualToString:@"Person Detail Segue"]) 
    { 
     NSLog(@"Setting PersonsTVC as a delegate of PersonDetailTVC"); 
     PersonDetailTVC *personDetailTVC = segue.destinationViewController; 
     personDetailTVC.delegate = self; 

     // Store selected Person in selectedPerson property 
     NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; 
     self.selectedPerson = [self.fetchedResultsController objectAtIndexPath:indexPath]; 

     NSLog(@"Passing selected person (%@) to PersonDetailTVC", self.selectedPerson.firstname); 
     personDetailTVC.person = self.selectedPerson; 
    } 
    else { 
     NSLog(@"Unidentified Segue Attempted!"); 
    } 
} 

- (void)theSaveButtonOnThePersonDetailTVCWasTapped:(PersonDetailTVC *)controller 
{ 
    // do something here like refreshing the table or whatever 

    // close the delegated view 
    [controller.navigationController popViewControllerAnimated:YES];  
} 

#pragma mark - 
#pragma mark Content Filtering 

-(void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope { 
    self.searchResults = [[self.fetchedResultsController fetchedObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) { 
     Person* person = evaluatedObject; 
     NSString* firstName = person.firstname; 

     //searchText having length < 3 should not be considered 
     if (!!searchText && [searchText length] < 3) { 
      return YES; 
     } 

     if ([scope isEqualToString:@"All"] || [firstName isEqualToString:scope]) { 
      return ([firstName rangeOfString:searchText].location != NSNotFound); 
     } 
     return NO; //if nothing matches 
    }]]; 
} 

#pragma mark - 
#pragma mark UISearchDisplayController Delegate Methods 

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString 
{ 
    [self filterContentForSearchText:searchString scope:@"All"]; 
    return YES; 
} 

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption 
{ 
    [self filterContentForSearchText:[self.searchDisplayController.searchBar text] scope:@"All"]; 
    return YES; 
} 



@end 
+0

Пожалуйста, следуйте [учебнику] (http://www.raywenderlich.com/16873/how-to-add-search-into-a-table-view), в частности раздел «Отправка данных в подробный вид ». Тем не менее, прежде чем вы отправляете такие запросы, убедитесь, что вы сделали достаточно исследований, иначе это увеличит нагрузку на сайт, и ваш вопрос будет проголосован и удален по очереди. –

+0

Я видел рекомендуемое учебное пособие, но я не нашел способ решить мою проблему, я вижу, что в рекомендуемом учебнике есть два табличных представления, и в моем приложении есть только один с двумя разными массивами, один для обычного просмотр со всеми записями и один с отфильтрованными записями. Прошу прощения, но мне нужна небольшая помощь ... – mvasco

+1

У вас появилась идея. моя рекомендация состояла бы в том, чтобы всегда использовать отфильтрованный результирующий набор в качестве источника данных для таблицы. Фильтрованный набор результатов будет отфильтрован в соответствии с фильтром поиска, который вы, возможно, уже выяснили. Затем в методе 'cellForRowAtIndexPath' удалите проверку' if (tableView == self.searchDisplayController.searchResultsTableView) 'и используйте' person = [self.searchResults objectAtIndex: indexPath.row]; 'всегда. –

ответ

1

Я предполагаю, что у вас есть настройки SEGUE в раскадровке (где вы управляете кнопку мыши перетаскивать из таблицы ячейку к вашему контроллеру подробных представлений), которая позволяет касаться обычных ячеек таблицы, чтобы перейти к подробному представлению, однако в ячейках просмотра таблицы поиска нет такой явной инструкции о том, что делать, когда прикасается.

Попробуйте добавить представление таблицы метод делегата didSelectRowAtIndexPath и начать переход, когда прикоснулся ячейка поиска таблицы:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 

    // Perform segue to detail when a SEARCH table cell is touched 
    if(tableView == self.searchDisplayController.searchResultsTableView) 
    { 
     [self performSegueWithIdentifier:@"Person Detail Segue" sender:tableView]; 
    } 

} 

Это должно выстрелить ваш метод prepareForSegue при прикосновении ячейки таблицы результатов поиска. По-видимому, вы уже реализовали логику для обработки «Person Detail Segue», но нам нужно добавить логику, чтобы различать, происходит ли segue из выбранной ячейки обычной таблицы или ячейки таблицы поиска.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
    if ([segue.identifier isEqualToString:@"Add Person Segue"]) 
    { 
     NSLog(@"Setting PersonsTVC as a delegate of PersonDetailTVC"); 
     PersonDetailTVC *personDetailTVC = segue.destinationViewController; 
     personDetailTVC.delegate = self; 

     NSLog(@"Creating a new person and passing it to PersonDetailTVC"); 
     Person *newPerson = [NSEntityDescription insertNewObjectForEntityForName:@"Person" 
                 inManagedObjectContext:self.managedObjectContext]; 

     personDetailTVC.person = newPerson; 
    } 
    else if ([segue.identifier isEqualToString:@"Person Detail Segue"]) 
    { 
     NSLog(@"Setting PersonsTVC as a delegate of PersonDetailTVC"); 
     PersonDetailTVC *personDetailTVC = segue.destinationViewController; 
     personDetailTVC.delegate = self; 

     // Store selected Person in selectedPerson property 
     if(sender == self.searchDisplayController.searchResultsTableView) 
     { 
      NSIndexPath *indexPath = [self.searchDisplayController.searchResultsTableView indexPathForSelectedRow]; 
      self.selectedPerson = [self.searchResults objectAtIndex:[indexPath row]]; 
     } 
     else 
     { 
      NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; 
      self.selectedPerson = [self.fetchedResultsController objectAtIndexPath:indexPath]; 
     } 

     NSLog(@"Passing selected person (%@) to PersonDetailTVC", self.selectedPerson.firstname); 
     personDetailTVC.person = self.selectedPerson; 
    } 
    else 
    { 
     NSLog(@"Unidentified Segue Attempted!"); 
    } 
} 

Могут быть некоторые ошибки реализации с моей стороны, но я считаю, что это общая стратегия, которая может сработать для вас. Надеюсь, это поможет.

+0

Спасибо MFarmer, ваше решение работает отлично, очень красивое решение. Я многое узнал из вашего кода. – mvasco

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