在我的应用程序中,我有一个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时,似乎没有任何事情发生......
答案 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问题的回答......