搜索栏不返回任何结果

Posted

技术标签:

【中文标题】搜索栏不返回任何结果【英文标题】:search bar does not return any results 【发布时间】:2013-04-23 12:52:39 【问题描述】:

我正在尝试使用NSpredicate 在我的应用程序中添加搜索功能。我试图让它发挥作用,但似乎看不出问题出在哪里。我重新创建了一个演示应用程序来展示我所做的事情。一切都显示在模拟器上,没有任何警告,但是在搜索栏中输入文本时,没有结果。搜索栏表格视图中没有显示任何内容。我正在使用搜索栏和搜索显示控制器对象,而且我的原始数据源是一个简单的 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

附言我使用的是 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>

【问题讨论】:

有人有兴趣投稿吗? 【参考方案1】:

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

【讨论】:

你是对的。我忘了更新 git hub 中的项目。基本上,在搜索处于活动状态的 segue 中的 if 语句中缺少这一行: NSIndexPath *indexPath = [self.searchDisplayController.searchResultsTableView indexPathForSelectedRow];很高兴你看到了那个,虽然这在我的项目中从来都不是问题,并且被检测到并修复了,但是谢谢。【参考方案2】:

你的问题是这一行的谓词

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

您的 _content 数组包含不支持包含运算符的 NSDictionaries。此外,单引号/双引号会导致 %@ 按字面意思使用。 (来自文档: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)

【讨论】:

您在回答中提到的代码不起作用。为了方便访问,我已将我的项目上传到 github。请你花点时间看一下。这是链接:github.com/AdrianPhillips/TableSearch 它在您的代码上运行良好。我将 line 59 替换为我在答案中写的内容,之后 searchResults 不为空。您可以在调试器中检查。虽然它确实崩溃了 - 但那是因为代码还有很多其他问题:) 你说得对,我忘记了如何设置单元格。在写这个项目的时候我一定喝了太多酒。:) 谢谢你的修复。我不得不添加修改你给我的代码,让它以正确的方式工作,但我不得不说,看到你写的修复程序让我大开眼界,看看我在哪里以及如何到达我想去的地方是,所以感谢您抽出宝贵的时间。我会检查你的答案是否正确。再次感谢 很高兴我能帮上忙。我将删除代码差异,因为它与这个问题无关。 没问题。你帮了大忙。我将在 girhub 上更新该项目,并将在我的原始答案中发布一个链接,以便其他人也可以使用它。干得好,继续努力。

以上是关于搜索栏不返回任何结果的主要内容,如果未能解决你的问题,请参考以下文章

iOS 搜索栏不显示结果

输入一个字母时,搜索栏不显示所有相关结果

搜索栏不一致错误(Swift)?

Drupal搜索没有为匿名用户产生任何结果[关闭]

Lucene .NET 搜索不返回任何结果

UISearchController 搜索栏不隐藏导航栏