UICollectionViewController& UISearchBar没有重新加载数据

时间:2014-08-01 19:45:14

标签: ios core-data uisearchbar nsfetchedresultscontroller

在我的应用程序中,我有一个CollectionViewController(PlayersCollectionView),它显示来自核心数据db的对象。我正在尝试实现UISearchBar来过滤集合视图结果。我通过segue从各种其他视图加载集合视图,并使用谓词来过滤数据,因此它只显示与从中加载的视图相关的对象。这一切都正常。

我在CollectionViewController中添加了一个UISearchBar,并试图让它工作。当我点击搜索按钮时,我设置了应该更改数据的第二个谓词。我调用[self.collectionview reloadData]但这似乎并没有真正重新加载数据...

以下是相关代码:

@interface PlayersCollectionViewController ()
@property(nonatomic, strong) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, strong) NSFetchedResultsController *fetchedResultsController;
@property (nonatomic, strong) NSCompoundPredicate *compoundPredicate;
@property (nonatomic, strong) NSPredicate *searchPredicate;
@end

@implementation PlayersCollectionViewController
@synthesize titleText, predicate, noResultsMSG;

- (void)viewDidLoad
{
[super viewDidLoad];
...
//search bar...
UISearchBar *searchBar = [UISearchBar new];
searchBar.delegate = self;
searchBar.showsCancelButton = YES;
searchBar.autocapitalizationType = UITextAutocapitalizationTypeWords;
searchBar.autocorrectionType = UITextAutocorrectionTypeNo;
searchBar.keyboardAppearance = UIKeyboardAppearanceDark;

self.navigationItem.titleView = searchBar;

}


#pragma mark UISearchBarDelegate
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[self applyFilters:[NSString stringWithString:searchBar.text]];
[searchBar resignFirstResponder];
}

- (void)applyFilters:(NSString*)searchString {

_searchPredicate = [NSPredicate predicateWithFormat:@"firstName like[cd] %@", searchString];

**[self.collectionView reloadData];**
}

#pragma mark - Fetched Results Controller Section
-(NSFetchedResultsController*) fetchedResultsController
{
if (_fetchedResultsController !=nil) {
    return _fetchedResultsController;
}

NSFetchRequest *fetchedRequest = [[NSFetchRequest alloc]init];
NSManagedObjectContext *context = [self managedObjectContext];
NSEntityDescription *entity =[NSEntityDescription entityForName:@"Player" inManagedObjectContext:context];
[fetchedRequest setEntity:entity];
NSSortDescriptor *firsttNameSortDescriptor = [[NSSortDescriptor alloc]initWithKey:@"firstName" ascending:YES];
NSSortDescriptor *lastNameSortDescriptor = [[NSSortDescriptor alloc]initWithKey:@"lastName" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:firsttNameSortDescriptor,lastNameSortDescriptor, nil];
fetchedRequest.sortDescriptors = sortDescriptors;

NSString *sPred = [NSString stringWithFormat:@"%@",_searchPredicate];
if ([sPred length] > 0 ) {
    if (![sPred isEqualToString:@"(null)"]) {
        _compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[predicate, _searchPredicate]];
        fetchedRequest.predicate = _compoundPredicate;
    }
} else {
    fetchedRequest.predicate = predicate;
}

_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchedRequest
                                                                managedObjectContext:context
                                                                  sectionNameKeyPath:nil
                                                                           cacheName:nil];

_fetchedResultsController.delegate = self;

return _fetchedResultsController;

}

在运行时,调用applyFilters方法并设置_searchPredicate,但是当我reloadData时,似乎没有任何事情发生......

2 个答案:

答案 0 :(得分:0)

在主线程以外的线程中执行此操作时,有时更新UI是错误的。我不确定这是不是问题,但值得一试!

尝试在主线程上运行reloadData消息:

dispatch_async(dispatch_get_main_queue(), ^{
    [self.collectionView reloadData];
});

答案 1 :(得分:0)

看起来,当你调用reloadData时,fetchedResultsController不会重建自己,除非你先杀掉它。

我通过改变构建谓词的方式并使用searchBar委托方法将其删除然后重新加载来修复此问题...

在我的fetchedResultsController中......     NSString * searchString = self.searchBar.text;     if(searchString.length> 0){         NSPredicate * firstNameSearchPredicate = [NSPredicate predicateWithFormat:@" firstName CONTAINS [cd]%@",searchString];         NSPredicate * lastNameSearchPredicate = [NSPredicate predicateWithFormat:@" lastName CONTAINS [cd]%@",searchString];         NSPredicate * orPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:[NSArray arrayWithObjects:firstNameSearchPredicate,lastNameSearchPredicate,nil]];

    NSPredicate *andPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:predicate, nil]];
    NSPredicate *finalPred = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:orPredicate, andPredicate, nil]];

    fetchedRequest.predicate = finalPred;
} else {
    fetchedRequest.predicate = predicate;
}

更新的搜索者委托方法......      - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {         self.fetchedResultsController = nil;

    NSError *error = nil;
    if (![[self fetchedResultsController]performFetch:&error]) {
        abort();
    }

    [self.collectionView reloadData];
    [self.searchBar becomeFirstResponder];
}

感谢Sergio对this问题的回答......