在我的 TableView 中实现 SearchBar 并使用 NSFetchedResultsController 和适当的谓词来使搜索工作
Posted
技术标签:
【中文标题】在我的 TableView 中实现 SearchBar 并使用 NSFetchedResultsController 和适当的谓词来使搜索工作【英文标题】:Implementing a SearchBar inside my TableView and using NSFetchedResultsController and the appropriate predicate to get searches working 【发布时间】:2013-10-25 07:02:31 【问题描述】:我有一个简单的 TableViewController,它有一个添加按钮,可以转到 ModalViewController;用户将文本添加到文本字段中,按保存并关闭,该条目将添加到核心数据中的实体和属性并显示在 TableViewController 中。它运作良好。
我首先从另一个按钮开始,该按钮在表格视图中拉出 UISearchBar,我可以搜索结果并将其拉回;那行得通。然后,我在 TableViewController 的底部添加了一个新选项卡,并设法在其中获取了搜索栏和表格。
现在,我希望 SearchBar 位于 Single Table View 的顶部,并且我希望用户能够键入并让它动态搜索 TableView。
我的 fetchRequest 目前对于 TableView 看起来像这样(没有搜索栏):
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Transaction" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"occasion.dateOfEvent" ascending:NO selector:@selector(localizedCaseInsensitiveCompare:)];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
[fetchRequest setFetchBatchSize:20];
//NSPredicate *pred = [NSPredicate predicateWithFormat:@"ANY whoBy.name CONTAINS[c] %@", self.searchBar.text];
//[fetchRequest setPredicate:pred];
NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:@"occasion.dateOfEvent" cacheName:nil];
self.fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
我正在搜索 Transaction 等。现在,此代码与我的其他具有搜索栏的视图控制器之间的唯一区别是 NSPredicate 未注释这一事实。搜索效果很好。如果我在这段代码中取消注释,当我运行它时,我会收到以下错误:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid predicate: nil RHS'
*** First throw call stack:
我了解发生了什么,因为我希望 TableViewController 显示时没有谓词,但是当我搜索时,我使那个谓词生效。任何有关如何开始这项工作的帮助将不胜感激!
我的搜索栏委托方法如下所示:
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
NSError *error;
if (![[self fetchedResultsController] performFetch:&error])
NSLog(@"Error in search %@, %@", error, [error userInfo]);
else
[self.tView reloadData];
[self.searchBar resignFirstResponder];
[noResultsLabel setHidden:_fetchedResultsController.fetchedObjects.count > 0];
【问题讨论】:
【参考方案1】:只有在给出搜索字符串时才应该设置谓词:
if ([self.searchBar.text length] > 0)
NSPredicate *pred = [NSPredicate predicateWithFormat:@"ANY whoBy.name CONTAINS[c] %@", self.searchBar.text];
[fetchRequest setPredicate:pred];
如果搜索字符串为空,则不设置谓词,因此返回所有结果。
【讨论】:
谢谢马丁 - 一如既往,你是一个很大的帮助!这摆脱了错误,断点显示它正在进入 searchbar 方法,但它没有刷新页面,或重新加载数据以显示显示结果。我已经更新了我的原始问题,以包含搜索栏是单独 UI 时的原始搜索栏方法,不同之处在于它正在重新加载数据,但我认为使用 NSFetched,我们不需要这样做。我也不需要在我的 TableViewController 中有一个 tableView 属性。当按下保存按钮时,有没有办法“重新加载”数据? @amitsbajaj:难道searchBarSearchButtonClicked
中的[self fetchedResultsController]
会返回一个旧 获取的结果控制器吗?如果谓词更改,您必须重新创建 FRC。 (这几乎是正确的。您也可以修改 fetch 请求。)
谢谢@Martin - 我认为 fetchedResultsController 是一样的。但是,在 fetchRquest 中,我有 if (_fetchedResultsController != nil) return _fetchedResultsController; 我不完全确定该怎么做才能使它正常工作,抱歉!
@amitsbajaj:您可能应该在searchBarSearchButtonClicked
中设置_fetchedResultsController = nil
,以便下一次调用[self fetchedResultsController]
创建一个新 FRC。
谢谢 Martin - 试过了 - 不幸的是没有改变.. 当我用字母或单词按 Search 时,它会删除键盘但保留完整的项目列表,而不仅仅是搜索的术语.. 抱歉,我知道这不是太难,但我感谢您抽出时间提供帮助!以上是关于在我的 TableView 中实现 SearchBar 并使用 NSFetchedResultsController 和适当的谓词来使搜索工作的主要内容,如果未能解决你的问题,请参考以下文章