ios - 带有来自 plist 的数据的 objective-c 过滤 TableView

标签 ios objective-c uitableview delegates uisearchdisplaycontroller

我的代码基于 this例子。初始数据显示在 TableView 中,但我不确定如何实现其余数据以显示过滤后的数据。我没有错误,搜索栏有效但没有过滤数据。这是我的 plist XML:

<dict>
    <key>Things to do</key>
    <array>
        <dict>
            <key>activity</key>
            <string>Watch movies or TV shows</string>
            <key>keywords</key>
            <array>
                <string>tv shows</string>
                <string>movies</string>
            </array>
        </dict>
        <dict>
            <key>activity</key>
            <string>Go Hiking</string>
            <key>keywords</key>
            <array>
                <string>hiking</string>
                <string>mountains</string>
            </array>
        </dict>
        <dict>
            <key>activity</key>
            <string>Video Games</string>
            <key>keywords</key>
            <array>
                <string>video games</string>
                <string>playstation</string>
                <string>xbox</string>
                <string>nintendo</string>
            </array>
        </dict>
    </array>
</dict>

这是我的 CategoriesViewController.m:

@interface CategoriesViewController () <UISearchDisplayDelegate>

@property (nonatomic, strong) NSMutableArray *tableData;
@property (nonatomic, strong) NSMutableArray *searchResults;
@property (weak, nonatomic) IBOutlet UISearchBar *searchBar;

@end

- (void)viewDidLoad
{
[super viewDidLoad];
NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"categories" ofType:@"plist"];
NSDictionary *categoriesDictionary = [[NSDictionary alloc] initWithContentsOfFile:plistPath];

self.tableData = categoriesDictionary[@"Things to do"];
//I think this next line is supposed to make it appear on top of the original table
self.searchResults = [NSMutableArray arrayWithCapacity:[self.tableData count]];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
    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 = self.tableData[indexPath.row][@"activity"];
    }

    return cell;
}

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{   
    [self.searchResults removeAllObjects];

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

    self.searchResults = [NSMutableArray arrayWithArray:[self.tableData filteredArrayUsingPredicate:resultPredicate]];
}

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

除了我更改了数据的来源外,它就像示例一样。如何根据关键字进行搜索?在此示例中,我是否只搜索初始 TableView 中包含的内容?感谢您的宝贵时间...

最佳答案

如果没有更多代码,很难说,但我认为您需要根据搜索字符串显示/隐藏两个表格 View 。

如果字符串为空,这将隐藏您的 searchResultsTableView 并显示您的其他 TableView ,我正在亲切地调用它 whatEverYouCalledYourOtherTableView

如果您的字符串不为空,则执行搜索,显示 searchResultsTableView,隐藏 whatEverYouCalledYourOtherTableView 并重新加载 searchResultsTableView 的数据。

-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
    if ([searchString isEqualToString:@""])
    {
        self.searchDisplayController.searchResultsTableView.hidden = YES;
        self.searchDisplayController.whatEverYouCalledYourOtherTableView.hidden = NO;
    }
    else
    {
        [self filterContentForSearchText:searchString
                                   scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
                           objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]];


        self.searchDisplayController.searchResultsTableView.hidden = NO;
        self.searchDisplayController.whatEverYouCalledYourOtherTableView.hidden = YES;
        [self.searchDisplayController.searchResultsTableView reloadData];
    }
    return YES;
}

您的 filterContentForSearchText 也是错误的。您有一组字典而不是字符串。首先只获取字符串,然后运行搜索。您最好立即创建一个字符串字典,让您的搜索正常工作的最简单方法就是这样。

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{   
    [self.searchResults removeAllObjects];

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

    NSMutableArray *activityArray = [[NSMutableArray alloc] init];
    for (int i = 0; i < [self.tableData count]; i++)
    {
        [activityArray addObject:self.tableData[i][@"activity"]];
    }

    self.searchResults = [NSMutableArray arrayWithArray:[activityArray filteredArrayUsingPredicate:resultPredicate]];
}

关于ios - 带有来自 plist 的数据的 objective-c 过滤 TableView ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21444522/

相关文章:

objective-c - 为表格 View (UITableView)绘制自定义单元格,更改颜色和分隔符颜色和宽度

ios - 未调用 UILabel 子类中的 UIGestureRecognizer

objective-c - 改变 NSProgressIndicator 的颜色?

objective-c - 如何从popoverController访问navigationController?

ios - 向 UItableview 中的每个单元格添加一个开关

ios - 'required' initializer 'init(coder:)' 必须由 'UITableViewCell' 的子类提供`

iphone - 滚动键盘覆盖的文本字段

objective-c - NSPredicate 匹配

ios - 如何在单元格、行和部分中构造不同的组件?

ios - UIView transitionWithView 和 UILabel 在过渡期间失去圆角