搜索栏不会返回任何结果

时间:2013-04-23 12:52:39

标签: xcode ios6 nspredicate uisearchbardisplaycontrol

我正在尝试使用NSpredicate在我的应用中添加搜索功能。我试图让它工作,似乎无法看到问题所在。我重新创建了一个演示应用程序,以显示我所做的。一切都显示在模拟器上没有任何警告,但在搜索栏中键入文本时,没有结果。搜索栏tableview中没有显示任何内容。我使用搜索栏和搜索显示控制器对象,我的原始数据源是一个简单的plist包含字典,每个字典有3个字符串。除搜索外,一切正常。有人可以看看我的代码,看看我哪里出错了吗?

这是我的.h文件:

#import <UIKit/UIKit.h>

@interface TableViewController : UITableViewController <UISearchBarDelegate>

@property (strong, nonatomic) NSArray *content;
@property (strong, nonatomic) NSMutableArray *searchResults;

@end

这是.m文件:

#import "TableViewController.h"
#import "DetailViewController.h"

@interface TableViewController ()

@end

@implementation TableViewController

@synthesize content = _content;
@synthesize searchResults = _searchResults;

-(NSArray *)content
{
if (!_content) {
    _content = [[NSArray alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Data" ofType:@"plist"]];
}
return _content;
}

- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
    // Custom initialization
}
return self;
}

- (void)viewDidLoad
{
[super viewDidLoad];

_searchResults = [[NSMutableArray alloc] init];

}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{

if (tableView == self.searchDisplayController.searchResultsTableView) {
    return [self.searchResults count];

} else {
    return [self.content count];

}
}

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{

[_searchResults removeAllObjects];

NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"SELF contains[cd] '%@'",searchText];

[_searchResults addObjectsFromArray:[_content filteredArrayUsingPredicate:resultPredicate]];
}

-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString
                           scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
                                  objectAtIndex:[self.searchDisplayController.searchBar
                                                 selectedScopeButtonIndex]]];

return YES;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

if (tableView == self.searchDisplayController.searchResultsTableView) {
    cell.textLabel.text = [_searchResults objectAtIndex:indexPath.row];
    cell.detailTextLabel.text = [_searchResults objectAtIndex:indexPath.row];
} else {
cell.textLabel.text = [[self.content objectAtIndex:indexPath.row] valueForKey:@"city"];
cell.detailTextLabel.text = [[self.content objectAtIndex:indexPath.row] valueForKey:@"state"];
}

return cell;
}



- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == self.searchDisplayController.searchResultsTableView) {
    [self performSegueWithIdentifier: @"showDetails" sender: self];
}
}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

{

if ([segue.identifier isEqualToString:@"showDetails"]) {

    NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
    DetailViewController *DVC = [segue destinationViewController];

    if ([self.searchDisplayController isActive]) {

    DVC.cityImageString = [_searchResults objectAtIndex:indexPath.row];
    DVC.cityTextString = [_searchResults objectAtIndex:indexPath.row];
    } else {

        DVC.cityImageString = [[self.content objectAtIndex:indexPath.row] valueForKey:@"cityImage"];
        DVC.cityTextString = [[self.content objectAtIndex:indexPath.row] valueForKey:@"cityText"];
    }

}
}

@end

P.S。我正在使用xcode 4.6 ios 6,我认为这不重要,可能与我的问题无关,而且,我已经通过IB添加了搜索栏,其代理和数据源自动连接到tableview。

感谢一大堆提前帮助。

编辑:

这是我的plist的结构,这是一个非常简单的结构,我认为它可以帮助某人给我一个答案。

     <?xml version="1.0" encoding="UTF-8"?>
     <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"   "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
       <plist version="1.0">
         <array>
      <dict>
    <key>city</key>
    <string>New York</string>
    <key>state</key>
    <string>NY</string>
    <key>cityText</key>
    <string>This is the description of the city that goes in the tex view just testing.</string>
    <key>cityImage</key>
    <string>acolon.png</string>
       </dict>
       <dict>
    <key>city</key>
    <string>Los Angeles</string>
    <key>state</key>
    <string>CA</string>
    <key>cityText</key>
    <string>This the second item&apos;s textview</string>
    <key>cityImage</key>
    <string>Piedirosso.jpg</string>
     </dict>
      <dict>
    <key>city</key>
    <string>Chicago</string>
    <key>state</key>
    <string>IL</string>
    <key>cityText</key>
    <string>here is the text view description for the third item.</string>
    <key>cityImage</key>
    <string>acolon.png</string>
</dict>
    </array>
    </plist>

2 个答案:

答案 0 :(得分:1)

干得好!但是检查最终代码,我发现如果从searchResults中选择一个单元格总是显示第一个单元格,例如搜索“s”结果:“Sandiago”和“Sprienfield”,如果选择“Sprienfield”,详细视图将为Sandiago。我找不到错误。

答案 1 :(得分:0)

你的问题是这一行的谓词

NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"SELF contains[cd] '%@'",searchText];

您的_content数组包含不支持contains运算符的NSDictionaries。此外,单/双引号会导致%@字面上使用。 (来自docs:Single or double quoting variables (or substitution variable strings) cause %@, %K, or $variable to be interpreted as a literal in the format string and so prevent any substitution)。将其更改为:

NSPredicate *pred = [NSPredicate predicateWithFormat: @"SELF['city'] contains[cd] %@ OR SELF['state'] contains[cd] %@ OR SELF['cityText'] contains[cd] %@", searchText, searchText, searchText];

(假设您要搜索所有三个值:city,state,cityText)