使用搜索解析UITableView

时间:2014-05-19 17:52:01

标签: ios uitableview parse-platform

我正在关注实施搜索的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

3 个答案:

答案 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];

   }

}