2013-11-23 28 views
1

我正在寫一個iOS應用程序(從iOS教程更新的應用程序)。它具有UITableView和UISearchBar的視圖(謝謝Ayan和Tommy)。我現在的問題在於,該表顯示了來自核心數據實體的所有記錄,當我點擊一個單元格時,該應用程序顯示了選定單元格的詳細視圖。這工作正常。問題是,在使用搜索方法後,如果我點擊搜索結果單元格,應用程序不會顯示選定單元格的詳細視圖。我想我必須確定搜索記錄的發件人的任何位置,但不知道如何或在何處包含此內容。 這是我此刻的代碼,任何幫助或提示,歡迎...謝謝你帶有tableview和搜索功能的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

我看過推薦的教程,但我沒有找到解決問題的方法,我看到在推薦教程中有兩個tableviews,在我的應用程序中只有一個有兩個不同的數組,一個是正常的包含所有記錄的視圖,以及包含已過濾記錄的視圖。我很抱歉,但我需要一點幫助... – mvasco

+1

好吧,有你的想法。我的建議是始終使用過濾的結果集作爲表的數據源。過濾的結果集將根據您可能已經想出的搜索過濾器進行過濾。然後在你的'cellForRowAtIndexPath'方法中刪除檢查'if(tableView == self.searchDisplayController.searchResultsTableView)'並且使用'person = [self.searchResults objectAtIndex:indexPath.row];'爲始終。 –

回答

1

我猜你在你的故事板有賽格瑞設置(你控制單擊從表中拖細胞添加到您的Detail View Controller中),它允許觸摸常規的表格視圖單元格以繼續到Detail View,但是您的搜索表格視圖單元格在觸摸時不知道該做什麼。

嘗試添加表視圖的委託方法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

相關問題