2009-09-13 43 views
17

Phương pháp hay nhất để lọc dữ liệu NSFetchedResultsController là gì? tôi có cần phải khởi tạo lại nó mỗi khi văn bản của thanh tìm kiếm thay đổi không?NSFetchedResultsController với tìm kiếm

Tôi đang sử dụng một UISearchDisplayControllers và tôi đang thực hiện:

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString; 

Thx.

+0

Bạn đã xử lý các phương pháp nguồn dữ liệu chế độ xem bảng như thế nào để chế độ xem bảng sẽ Biết có hiển thị 'danh sách được lọc' hay không? – CraigH

+1

Câu trả lời ở đây rất hữu ích http://stackoverflow.com/questions/4471289/how-to-filter-nsfetchedresultscontroller-coredata-with-uisearchdisplaycontroll/4481896#4481896 – acecapades

+0

Đây là những gì tôi đã làm: http: // stackoverflow .com/questions/4471289/how-to-filter-nsfetchedresultscontroller-coredata-with-uisearchdisplaycontrolle/4856118 # 4856118 –

Trả lời

17

thế nào là mã câu trả lời Guy của bất kỳ khác biệt so với các câu hỏi? Theo như tôi có thể đoán, phương thức filterContentForSearchText: scope được gọi bởi các phương thức shouldReload?

Dù sao, đây là một số mã tương tự mà tôi đã thêm vào trong mẫu CoreDataBooks để bao gồm tìm kiếm. Thêm một bộ điều khiển hiển thị tìm kiếm trong IB cho ví dụ CoreDataBooks. Sau đó, tôi đã thêm mã vào RootViewController.m như sau:

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString { 
NSInteger searchOption = controller.searchBar.selectedScopeButtonIndex; 
return [self searchDisplayController:controller shouldReloadTableForSearchString:searchString searchScope:searchOption]; 
} 

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption { 
NSString* searchString = controller.searchBar.text; 
return [self searchDisplayController:controller shouldReloadTableForSearchString:searchString searchScope:searchOption]; 
} 

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString*)searchString searchScope:(NSInteger)searchOption { 

NSPredicate *predicate = nil; 
if ([searchString length]) 
    if (searchOption == 0) // full text, in my implementation. Other scope button titles are "Author", "Title" 
    predicate = [NSPredicate predicateWithFormat:@"title contains[cd] %@ OR author contains[cd] %@", searchString, searchString]; 
    else 
    // docs say keys are case insensitive, but apparently not so. 
    predicate = [NSPredicate predicateWithFormat:@"%K contains[cd] %@", [[controller.searchBar.scopeButtonTitles objectAtIndex:searchOption] lowercaseString], searchString]; 
[fetchedResultsController.fetchRequest setPredicate:predicate]; 

    NSError *error = nil; 
    if (![[self fetchedResultsController] performFetch:&error]) { 
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
    abort(); 
    }   

return YES; 
} 

PS. Để trả lời Vivas, sử dụng UISearchDisplayController, nó sẽ tự động tạo ra một khung nhìn bảng mới để chồng lên danh sách được lọc. Bạn có thể kiểm tra xem tableView nào đang được sử dụng như trong tài liệu, nhưng trong thiết lập đơn giản nhất nó chỉ hoạt động vì fetchedResultsController hiển thị phiên bản đã lọc trong khung nhìn của bảng tìm kiếm hoặc hiển thị tất cả dữ liệu trong dạng xem bảng của bạn.

+0

Hành vi lạ ... các đối tượng được lọc, nhưng khi tôi di chuyển xuống khung nhìn nó đưa ra một ngoại lệ, bởi vì fetchController không có đối tượng ở chỉ mục cụ thể ... điều gì có thể sai? xin vui lòng, giúp đỡ –

+0

Tôi đã tìm ra vấn đề của mình ... khi tôi nhận được kết quả lọc, chúng được hiển thị trong tableView được định cấu hình theo cùng cách và khi tôi cuộn đến hàng số X nơi số hàng thực nhỏ hơn X ... tôi nên làm .. –

8

Appearantly đây là một cách tốt hơn:

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope 
{ 
    self.savedSearchTerm = searchText; 

    freshData = NO; 
    if (searchText !=nil) 
    { 
      NSPredicate *predicate =[NSPredicate predicateWithFormat:@"name contains[cd] %@", searchText]; 
      [fetchedResultsController.fetchRequest setPredicate:predicate]; 
    } 
    else 
    { 
      NSPredicate *predicate =[NSPredicate predicateWithFormat:@"All"]; 
      [fetchedResultsController.fetchRequest setPredicate:predicate]; 
    } 

    NSError *error = nil; 
    if (![[self fetchedResultsController] performFetch:&error]) { 
      // Handle error 
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
      exit(-1); // Fail 
    }   

    [self.tableView reloadData]; 

    // [searchBar resignFirstResponder]; 
    // [_shadeView setAlpha:0.0f]; 

} 
+29

lối ra (-1) hơi khắc nghiệt. – 0xced

+5

Tài liệu Appl nói rằng yêu cầu tìm nạp không nên thay đổi - chúng đặc biệt nói rằng bạn không nên thay đổi vị từ. –

+1

@RogerNolan Bạn có chắc chắn không? Xem [Tham khảo lớp NSFetchedResultsController: Sửa đổi yêu cầu tìm nạp] (http://j.mp/z3W7QK). Ba bước này làm việc tốt cho tôi và thậm chí tôi sửa đổi vị từ của yêu cầu tìm nạp. – ma11hew28

Các vấn đề liên quan