我正在关注实施搜索的AppCoda教程;但是,我从Parse中拉出表格视图的标题,并且无法使搜索功能起作用。当我开始在搜索中输入时引发异常:
'无法在集合中使用/ contains运算符{ buildingLat =" 42.726366&#34 ;; buildingLong =" -84.480642&#34 ;; buildingTitle ="国际中心&#34 ;; (不是集合)'
这是我的表视图控制器的代码:
#import "BuildingsViewController.h"
#import <Parse/Parse.h>
@interface BuildingsViewController ()
@end
@implementation BuildingsViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[self performSelector:@selector(retrieveBuildings)];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - TableView Setup
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.buildingsArray count];
if (tableView == self.searchDisplayController.searchResultsTableView) {
return [self.searchResults count];
} else {
return [self.buildingsArray count];
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"buildingsCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
PFObject *tempObject = [self.buildingsArray objectAtIndex:indexPath.row];
cell.textLabel.text = [tempObject objectForKey:@"buildingTitle"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (tableView == self.searchDisplayController.searchResultsTableView) {
cell.textLabel.text = [self.searchResults objectAtIndex:indexPath.row];
} else {
cell.textLabel.text = [tempObject objectForKey:@"buildingTitle"];
}
return cell;
}
#pragma mark - Helper Methods
-(void)retrieveBuildings
{
PFQuery *retrieveBuildings = [PFQuery queryWithClassName:@"buildingsList"];
[retrieveBuildings findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
self.buildingsArray = [[NSArray alloc] initWithArray:objects];
}
[self.tableView reloadData];
}];
}
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:@"SELF contains[cd] %@",
searchText];
self.searchResults = [self.buildingsArray filteredArrayUsingPredicate:resultPredicate];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller
shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex:[self.searchDisplayController.searchBar
selectedScopeButtonIndex]]];
return YES;
}
@end
答案 0 :(得分:0)
您正尝试在NSPredicate
数组上应用PFObjects
,因此您的谓词需要如下所示:
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:@"variableNameToSearchOn contains[cd] %@",
searchText];
编辑:
你可以试试这个:
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:@"buildingTitle contains[c] %@",
searchText];
答案 1 :(得分:0)
我认为你走在正确的轨道上......
我的理解是你收到了一系列字典,并将收到的数组传递给你声明的buildingsArray
。这不是问题。我理解的问题是,您正在尝试从没有相应代码的其中一个字典中检索其中一个值。
您正在两个地方尝试此过程。
我指的是cellForRowAtIndexPath
方法中的代码。
另外,不再需要检查cell == nil
,因此您可以删除包裹您的单元格设置器if
)的cell = [[UITableViewCell...
语句。
<强> UPDATE ... 强>
删除nil
的此检查时代码中的崩溃是由于您没有为searchResultsTableView
注册重用标识符。
要更正您的搜索和数据解析,我建议您按照我包含的示例代码进行操作。
添加新的媒体资源tempMutableArray
,然后从static
移除cellForRowAtIndexPath
声明,并将其放在#import
和@interface
行之间,如下所示。
#import <Parse/Parse.h>
static NSString *CellIdentifier = @"buildingsCell"; // relocated static declaration
@interface BuildingsViewController ()
@property (nonatomic, strong) NSMutableArray *tempMutableArray;
@end
// implementation
然后在您的viewDidLoad
TVC生命周期方法中,实例化NSMutableArray
,并将UITableViewCell
类和CellIdentifier
重用标识符注册到searchResultsTableView
... < / p>
- (void)viewDidLoad {
[super viewDidLoad];
//...your other code...
[self setTempMutableArray:[[NSMutableArray alloc] init]];
[self.searchDisplayController.searchResultsTableView registerClass:[UITableViewCell class]
forCellReuseIdentifier:CellIdentifier];
}
...
您的新替换cellForRowAtIndexPath:
方法
要从Parse正确解析您的信息,请尝试以下操作...
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = nil;
if (tableView == self.searchDisplayController.searchResultsTableView) {
cell = [self.searchDisplayController.searchResultsTableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.textLabel.text = [self.searchResults objectAtIndex:indexPath.row];
} else {
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSDictionary *tempDict = nil;
NSString *tempString = nil;
tempDict = [self.buildingsArray objectAtIndex:indexPath.row];
tempString = [tempDict objectForKey:@"buildingTitle"];
[cell.textLabel setText:tempString];
}
return cell;
}
您还需要在filterContentForSearchText:
方法中完成类似操作。
您的新替换filterContentForSearchText:
方法
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *resultPredicate = nil;
[self.tempMutableArray removeAllObjects];
for (NSDictionary *tempDict in self.buildingsArray) {
NSString *tempString = nil;
tempString = [tempDict objectForKey:@"buildingTitle"];
[self.tempMutableArray addObject:tempString];
}
resultPredicate = [NSPredicate predicateWithFormat:@"SELF contains[cd] %@", searchText];
self.searchResults = [self.tempMutableArray filteredArrayUsingPredicate:resultPredicate];
}
...继续以前的反应
我的理解......您的代码中发生的事情是PFQuery
在其完成块中返回NSArray
。您可以根据此属性设置属性buildingsArray
,也为NSArray
。据我所知,您不再需要将返回的数据视为PFObject
。
让我知道你怎么走。
答案 2 :(得分:0)
#pragma mark UISearchBarDelegate
-(void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar{
sar.showsCancelButton=YES;
sar.autocorrectionType = UITextAutocorrectionTypeNo;
}
- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
NSString* newText = [searchBar.text stringByReplacingCharactersInRange:range withString:text];
searchStr = newText;
[self DisplayMatchSearch];
[tblView reloadData];
return YES;
}
-(BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar{
//write code for requset data from database search.....
sar.showsCancelButton=NO;
[sar resignFirstResponder];
return YES;
}
-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar{
[self getAlldata];
@try {
[tblBeepUsers reloadData];
}
@catch (NSException * e) {
}
[sar resignFirstResponder];
sar.text=@"";
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{
searchStr = sar.text;
[sar resignFirstResponder];
[self DisplayMatchSearch];
[tblView reloadData];
}
-(void)DisplayMatchSearch{
if (searchStr && searchStr.length) {
//temp array
arrLocation = [[NSMutableArray alloc] init];
//parsed array self.buildingsArray
for (NSDictionary *dictionary in self.buildingsArray)
{
if ([[dictionary objectForKey:@"name"] rangeOfString:searchStr options:NSCaseInsensitiveSearch].location != NSNotFound) {
[arrLocation addObject:dictionary];
}
}
[tblview reloadData];
}
}