第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何使用UISearchDisplayController / UISearchBar過濾

如何使用UISearchDisplayController / UISearchBar過濾

一只甜甜圈 2019-07-27 15:07:09
如何使用UISearchDisplayController / UISearchBar過濾NSFetchedResultsController(CoreData)我正在嘗試在基于CoreData的iPhone應(yīng)用程序中實現(xiàn)搜索代碼。我不知道該怎么辦。該應(yīng)用程序已經(jīng)有一個帶有謂詞的NSFetchedResultsController,用于檢索主TableView的數(shù)據(jù)。在改變太多代碼之前,我想確保自己走在正確的道路上。我很困惑,因為很多例子都是基于數(shù)組而不是CoreData。以下是一些問題:我是否需要第二個NSFetchedResultsController只檢索匹配的項目,或者我可以使用與主TableView相同的項目嗎?如果我使用相同的,它是否像清除FRC緩存然后更改handleSearchForTerm:searchString方法中的謂詞一樣簡單?謂詞是否必須包含初始謂詞以及搜索詞,還是記得它首先使用謂詞來檢索數(shù)據(jù)?我如何回到原始結(jié)果?我只是將搜索謂詞設(shè)置為nil嗎?難道不會殺掉用于首先檢索FRC結(jié)果的原始謂詞嗎?如果有人使用FRC搜索任何代碼示例,我將不勝感激!
查看完整描述

3 回答

?
慕容708150

TA貢獻1831條經(jīng)驗 獲得超4個贊

我實際上只是在我的一個項目上實現(xiàn)了這個(你的問題和另一個錯誤的答案暗示了該做什么)。我嘗試了Sergio的回答但在實際運行在設(shè)備上時遇到異常問題。

是的,您創(chuàng)建了兩個獲取結(jié)果控制器:一個用于正常顯示,另一個用于UISearchBar的表視圖。

如果您只使用一個FRC(NSFetchedResultsController),則原始UITableView(不是搜索時處于活動狀態(tài)的搜索表視圖)可能會在您搜索時調(diào)用回調(diào)并嘗試錯誤地使用FRC的過濾版本,您將看到異常拋出部分中不正確數(shù)量的部分或行。

這是我做的:我有兩個FRC可用作屬性fetchedResultsController和searchFetchedResultsController。除非有搜索,否則不應(yīng)使用searchFetchedResultsController(當(dāng)取消搜索時,您可以在下面看到該對象已被釋放)。所有UITableView方法都必須弄清楚它將查詢哪個表視圖以及從中提取信息的適用FRC。FRC委托方法還必須確定要更新的tableView。

令人驚訝的是,這有多少是樣板代碼。

頭文件的相關(guān)位:

@interface BlahViewController : UITableViewController <UISearchBarDelegate, NSFetchedResultsControllerDelegate, UISearchDisplayDelegate> {
    // other class ivars

    // required ivars for this example
    NSFetchedResultsController *fetchedResultsController_;
    NSFetchedResultsController *searchFetchedResultsController_;
    NSManagedObjectContext *managedObjectContext_;

    // The saved state of the search UI if a memory warning removed the view.
    NSString        *savedSearchTerm_;
    NSInteger       savedScopeButtonIndex_;
    BOOL            searchWasActive_;}@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;@property (nonatomic, retain, readonly) NSFetchedResultsController *fetchedResultsController;@property (nonatomic, copy) NSString *savedSearchTerm;@property (nonatomic) NSInteger savedScopeButtonIndex;@property (nonatomic) BOOL searchWasActive;

相關(guān)位的實現(xiàn)文件:

@interface BlahViewController ()@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;@property (nonatomic, retain) NSFetchedResultsController *searchFetchedResultsController;@property (nonatomic, retain) UISearchDisplayController *mySearchDisplayController;@end

在使用所有UITableViewDelegate / DataSource方法時,我創(chuàng)建了一個有用的方法來檢索正確的FRC:

- (NSFetchedResultsController *)fetchedResultsControllerForTableView:(UITableView *)tableView{
    return tableView == self.tableView ? self.fetchedResultsController : self.searchFetchedResultsController;}- (void)fetchedResultsController:(NSFetchedResultsController *)fetchedResultsController configureCell:(UITableViewCell *)theCell atIndexPath:(NSIndexPath *)theIndexPath{
    // your cell guts here}- (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)theIndexPath{
    CallTableCell *cell = (CallTableCell *)[theTableView dequeueReusableCellWithIdentifier:@"CallTableCell"];
    if (cell == nil) 
    {
        cell = [[[CallTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CallTableCell"] autorelease];
    }

    [self fetchedResultsController:[self fetchedResultsControllerForTableView:theTableView] configureCell:cell atIndexPath:theIndexPath];
    return cell;}- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{
    NSInteger count = [[[self fetchedResultsControllerForTableView:tableView] sections] count];

    return count;}- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{
    NSInteger numberOfRows = 0;
    NSFetchedResultsController *fetchController = [self fetchedResultsControllerForTableView:tableView];
    NSArray *sections = fetchController.sections;
    if(sections.count > 0) 
    {
        id <NSFetchedResultsSectionInfo> sectionInfo = [sections objectAtIndex:section];
        numberOfRows = [sectionInfo numberOfObjects];
    }

    return numberOfRows;}

委托搜索欄的方法:

#pragma mark -#pragma mark Content Filtering- (void)filterContentForSearchText:(NSString*)searchText scope:(NSInteger)scope{
    // update the filter, in this case just blow away the FRC and let lazy evaluation create another with the relevant search info
    self.searchFetchedResultsController.delegate = nil;
    self.searchFetchedResultsController = nil;
    // if you care about the scope save off the index to be used by the serchFetchedResultsController
    //self.savedScopeButtonIndex = scope;}#pragma mark -#pragma mark Search Bar - (void)searchDisplayController:(UISearchDisplayController *)controller willUnloadSearchResultsTableView:(UITableView *)tableView;{
    // search is done so get rid of the search FRC and reclaim memory
    self.searchFetchedResultsController.delegate = nil;
    self.searchFetchedResultsController = nil;}- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString{
    [self filterContentForSearchText:searchString 
                               scope:[self.searchDisplayController.searchBar selectedScopeButtonIndex]];

    // Return YES to cause the search result table view to be reloaded.
    return YES;}- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption{
    [self filterContentForSearchText:[self.searchDisplayController.searchBar text] 
                               scope:[self.searchDisplayController.searchBar selectedScopeButtonIndex]];

    // Return YES to cause the search result table view to be reloaded.
    return YES;}

從FRC委托方法獲取更新時,請確保使用正確的表視圖:

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller 
{
    UITableView *tableView = controller == self.fetchedResultsController ? self.tableView : self.searchDisplayController.searchResultsTableView;
    [tableView beginUpdates];}- (void)controller:(NSFetchedResultsController *)controller 
  didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
           atIndex:(NSUInteger)sectionIndex 
     forChangeType:(NSFetchedResultsChangeType)type 
{
    UITableView *tableView = controller == self.fetchedResultsController ? self.tableView : self.searchDisplayController.searchResultsTableView;

    switch(type) 
    {
        case NSFetchedResultsChangeInsert:
            [tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }}- (void)controller:(NSFetchedResultsController *)controller 
   didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)theIndexPath 
     forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath 
{
    UITableView *tableView = controller == self.fetchedResultsController ? self.tableView : self.searchDisplayController.searchResultsTableView;

    switch(type) 
    {
        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:theIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeUpdate:
            [self fetchedResultsController:controller configureCell:[tableView cellForRowAtIndexPath:theIndexPath] atIndexPath:theIndexPath];
            break;

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:theIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationFade];
            break;
    }}- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller 
{
    UITableView *tableView = controller == self.fetchedResultsController ? self.tableView : self.searchDisplayController.searchResultsTableView;
    [tableView endUpdates];}

其他查看信息:

- (void)loadView 
{   
    [super loadView];
    UISearchBar *searchBar = [[[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width, 44.0)] autorelease];
    searchBar.autoresizingMask = (UIViewAutoresizingFlexibleWidth);
    searchBar.autocorrectionType = UITextAutocorrectionTypeNo;
    self.tableView.tableHeaderView = searchBar;

    self.mySearchDisplayController = [[[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self] autorelease];
    self.mySearchDisplayController.delegate = self;
    self.mySearchDisplayController.searchResultsDataSource = self;
    self.mySearchDisplayController.searchResultsDelegate = self;}- (void)didReceiveMemoryWarning{
    self.searchWasActive = [self.searchDisplayController isActive];
    self.savedSearchTerm = [self.searchDisplayController.searchBar text];
    self.savedScopeButtonIndex = [self.searchDisplayController.searchBar selectedScopeButtonIndex];

    fetchedResultsController_.delegate = nil;
    [fetchedResultsController_ release];
    fetchedResultsController_ = nil;
    searchFetchedResultsController_.delegate = nil;
    [searchFetchedResultsController_ release];
    searchFetchedResultsController_ = nil;

    [super didReceiveMemoryWarning];}- (void)viewDidDisappear:(BOOL)animated{
    // save the state of the search UI so that it can be restored if the view is re-created
    self.searchWasActive = [self.searchDisplayController isActive];
    self.savedSearchTerm = [self.searchDisplayController.searchBar text];
    self.savedScopeButtonIndex = [self.searchDisplayController.searchBar selectedScopeButtonIndex];}- (void)viewDidLoad{
    // restore search settings if they were saved in didReceiveMemoryWarning.
    if (self.savedSearchTerm)
    {
        [self.searchDisplayController setActive:self.searchWasActive];
        [self.searchDisplayController.searchBar setSelectedScopeButtonIndex:self.savedScopeButtonIndex];
        [self.searchDisplayController.searchBar setText:savedSearchTerm];

        self.savedSearchTerm = nil;
    }}

FRC創(chuàng)建代碼:

- (NSFetchedResultsController *)newFetchedResultsControllerWithSearch:(NSString *)searchString{
    NSArray *sortDescriptors = // your sort descriptors here
    NSPredicate *filterPredicate = // your predicate here

    /*
     Set up the fetched results controller.
     */
    // Create the fetch request for the entity.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *callEntity = [MTCall entityInManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:callEntity];

    NSMutableArray *predicateArray = [NSMutableArray array];
    if(searchString.length)
    {
        // your search predicate(s) are added to this array
        [predicateArray addObject:[NSPredicate predicateWithFormat:@"name CONTAINS[cd] %@", searchString]];
        // finally add the filter predicate for this view
        if(filterPredicate)
        {
            filterPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:filterPredicate, [NSCompoundPredicate orPredicateWithSubpredicates:predicateArray], nil]];
        }
        else
        {
            filterPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:predicateArray];
        }
    }
    [fetchRequest setPredicate:filterPredicate];

    // Set the batch size to a suitable number.
    [fetchRequest setFetchBatchSize:20];

    [fetchRequest setSortDescriptors:sortDescriptors];

    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
                                                                                                managedObjectContext:self.managedObjectContext 
                                                                                                  sectionNameKeyPath:nil 
                                                                                                           cacheName:nil];
    aFetchedResultsController.delegate = self;

    [fetchRequest release];

    NSError *error = nil;
    if (![aFetchedResultsController performFetch:&error]) 
    {
        /*
         Replace this implementation with code to handle the error appropriately.

         abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
         */
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    return aFetchedResultsController;}    - (NSFetchedResultsController *)fetchedResultsController 
{
    if (fetchedResultsController_ != nil) 
    {
        return fetchedResultsController_;
    }
    fetchedResultsController_ = [self newFetchedResultsControllerWithSearch:nil];
    return [[fetchedResultsController_ retain] autorelease];}   - (NSFetchedResultsController *)searchFetchedResultsController 
{
    if (searchFetchedResultsController_ != nil) 
    {
        return searchFetchedResultsController_;
    }
    searchFetchedResultsController_ = [self newFetchedResultsControllerWithSearch:self.searchDisplayController.searchBar.text];
    return [[searchFetchedResultsController_ retain] autorelease];}


查看完整回答
反對 回復(fù) 2019-07-27
?
夢里花落0921

TA貢獻1772條經(jīng)驗 獲得超6個贊

有人評論說,這可以用一個單獨完成NSFetchedResultsController。這就是我所做的,這里是細節(jié)。此解決方案假設(shè)您只想過濾表格并維護搜索結(jié)果的所有其他方面(排序順序,單元格布局等)。

首先,在UITableViewController子類中定義兩個屬性(使用適當(dāng)?shù)腀synthesize和dealloc,如果適用):

@property (nonatomic, retain) UISearchDisplayController *searchController;@property (nonatomic, retain) NSString *searchString;

其次,初始化子類viewDidLoad:方法中的搜索欄UITableViewController

UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0,0,self.tableView.frame.size.width,44)]; searchBar.placeholder = @"Search";searchBar.delegate = self;self.searchController = [[[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self] autorelease];self.searchController.delegate = self;self.searchController.searchResultsDataSource = self;   self.searchController.searchResultsDelegate = self; self.tableView.tableHeaderView = self.searchController.searchBar;[searchBar release];

第三,實現(xiàn)這樣的UISearchDisplayController委托方法:

// This gets called when you start typing text into the search bar-(BOOL)searchDisplayController:(UISearchDisplayController *)_controller shouldReloadTableForSearchString:(NSString *)_searchString {
   self.searchString = _searchString;
   self.fetchedResultsController = nil;
   return YES;}// This gets called when you cancel or close the search bar-(void)searchDisplayController:(UISearchDisplayController *)controller willUnloadSearchResultsTableView:(UITableView *)tableView {
   self.searchString = nil;
   self.fetchedResultsController = nil;
   [self.tableView reloadData];}

最后,在fetchedResultsController方法中更改NSPredicate依賴if self.searchString是否定義:

-(NSFetchedResultsController *)fetchedResultsController {
   if (fetchedResultsController == nil) {

       // removed for brevity

      NSPredicate *predicate;

      if (self.searchString) {
         // predicate that uses searchString (used by UISearchDisplayController)
         // e.g., [NSPredicate predicateWithFormat:@"name CONTAINS[cd] %@", self.searchString];
          predicate = ... 
      } else {
         predicate = ... // predicate without searchString (used by UITableViewController)
      }

      // removed for brevity

   }

   return fetchedResultsController;}


查看完整回答
反對 回復(fù) 2019-07-27
  • 3 回答
  • 0 關(guān)注
  • 614 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號