【问题标题】:NSPredicate not filtering UITableView?NSPredicate 不过滤 UITableView?
【发布时间】:2013-05-23 01:57:51
【问题描述】:

由于某种原因,NSPredicate 没有过滤我的 UITableView(它应该通过 UIPickerView 中的选择过滤我的 TableView)。用户做出他们的pickerview选择,按下GO按钮(segue从Pickerview连接到Table View控制器)。

知道为什么它不起作用吗?请参阅下面的代码。

ViewController.m(表视图控制器)

- (int)numberOfSectionsInTableView: (UITableView *)tableview

{

    return 1;

}

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

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




    } else {
        return [Strains count];

    }



}



- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{


    static NSString *strainTableIdentifier = @"StrainTableCell";

    StrainTableCell *cell = (StrainTableCell *)[tableView dequeueReusableCellWithIdentifier:strainTableIdentifier];
    if (cell == nil) 


        cell = [[StrainTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:strainTableIdentifier];



        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"StrainTableCell" owner:self options:nil];
        cell = [nib objectAtIndex:0];

    if (tableView == self.searchDisplayController.searchResultsTableView) {
       NSLog(@"Using the search results");

        cell.titleLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:@"Title"];
        cell.descriptionLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:@"Description"];
        cell.ratingLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:@"Rating"];
        cell.ailmentLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:@"Ailment"];
        cell.actionLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:@"Action"];
        cell.ingestLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:@"Ingestion"];

        NSLog(@"%@", searchResults);


    } else {
        NSLog(@"Using the FULL LIST!!");
        cell.titleLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:@"Title"];
         cell.descriptionLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:@"Description"];
         cell.ratingLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:@"Rating"];
        cell.ailmentLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:@"Ailment"];
        cell.actionLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:@"Action"];
        cell.ingestLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:@"Ingestion"];

    }


return cell;

}




- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
    NSPredicate *resultPredicate = [NSPredicate 
                                    predicateWithFormat:@"Title contains[cd] %@",
                                    searchText];

    searchResults = [Strains filteredArrayUsingPredicate:resultPredicate];


}





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

    return YES;
}



- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {


    StrainDetailViewController *detailViewController = [[StrainDetailViewController alloc] initWithNibName:@"StrainDetailViewController" bundle:nil]; if ([searchResults count]) {

        detailViewController.title = [[searchResults objectAtIndex:indexPath.row] objectForKey:@"Title"];
        detailViewController.strainDetail = [searchResults objectAtIndex:indexPath.row];

    } else {

        detailViewController.title = [[Strains objectAtIndex:indexPath.row] objectForKey:@"Title"];
        detailViewController.strainDetail = [Strains objectAtIndex:indexPath.row];
        NSLog(@"%@", Strains);
    }

    [self.navigationController pushViewController:detailViewController animated:YES];



    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}


- (void)PickerViewControllerDidFinish:(PickerViewController *)viewController {
  [self.navigationController popViewControllerAnimated:YES];

}

PickerViewController.h

@protocol PickerViewControllerDelegate;

@interface PickerViewController : UIViewController {


    UIPickerView *pickerView;

    NSMutableArray *array1;
    NSMutableArray *array2;
    NSMutableArray *array3;



    NSArray *Strains;
    NSArray *searchResults;

    NSMutableData *data;



}

- (IBAction)buttonpressed:(UIButton *)sender;

@property (nonatomic, weak) id<PickerViewControllerDelegate> delegate;

@property (nonatomic, retain) IBOutlet UIPickerView *pickerView;

- (void)populateArray1;
- (void)populateArray2;
- (void)populateArray3;




@end

@protocol PickerViewControllerDelegate <NSObject>

- (void)PickerViewControllerDidFinish:(PickerViewController*)viewController;

@end

PickerViewController.m

  #pragma mark -
#pragma mark picker view methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;
{
    return 3;
}

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
    if (component == 0)
    {
        NSLog(@"you selected %@", [array1 objectAtIndex:row]);

    }

    if (component == 1)
    {
        NSLog(@"you selected %@", [array2 objectAtIndex:row]);

    }


    if (component == 2)
    {
        NSLog(@"you selected %@", [array3 objectAtIndex:row]);

    }




}




- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
{




    if (component == 0)
    {
        return [array1 count];
    }

    if (component == 1)
    {
        return [array2 count];
    }


    if (component == 2)
    {
        return [array3 count];
    }

    else
    {
        return [array1 count];
    }
}

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
{

    if (component == 0)
    {
        return [array1 objectAtIndex:row];
    }

    if (component == 1)
    {
        return [array2 objectAtIndex:row];
    }

    if (component == 2)
    {
        return [array3 objectAtIndex:row];
    }

    else
    {
        return [array2 objectAtIndex:row];
    }
}



- (void)populateArray1
{
    array1 = [[NSMutableArray alloc] init];

    [array1 addObject:@"Arthritis"];
    [array1 addObject:@"Cancer"];
    [array1 addObject:@"HIV"];
    [array1 addObject:@"Migraines"];
    [array1 addObject:@"Insomnia"];

}

- (void)populateArray2
{
    array2 = [[NSMutableArray alloc] init];

    [array2 addObject:@"Nausea"];
    [array2 addObject:@"Pain"];
    [array2 addObject:@"Appetite"];
    [array2 addObject:@"Fever"];
    [array2 addObject:@"Exhaustion"];

}

- (void)populateArray3
{
    array3 = [[NSMutableArray alloc] init];

    [array3 addObject:@"Oil"];
    [array3 addObject:@"Plant"];
    [array3 addObject:@"Edible"];
    [array3 addObject:@"Powder"];


}



- (IBAction)buttonpressed:(UIButton *)sender {

        NSLog(@"Button Pushed!");

}



- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Make sure your segue name in storyboard is the same as this line
    if ([[segue identifier] isEqualToString:@"pickerGo"])
    {
        // Get reference to the destination view controller
        ViewController *strainTableView = [(UINavigationController *)[segue destinationViewController] topViewController];

        NSPredicate *ailmentPredicate = [NSPredicate predicateWithFormat:@"Ailment contains[cd] %@", [pickerView selectedRowInComponent:0]];

        NSPredicate *actionPredicate = [NSPredicate predicateWithFormat:@"Action contains[cd] %@", [pickerView selectedRowInComponent:1]];

        NSPredicate *ingestPredicate = [NSPredicate predicateWithFormat:@"Ingestion contains[cd] %@", [pickerView selectedRowInComponent:2]];


        NSCompoundPredicate *resultPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects: ailmentPredicate,actionPredicate,ingestPredicate, nil]];

        searchResults = [Strains filteredArrayUsingPredicate:resultPredicate];

        // Pass any objects to the view controller here, like...
        [strainTableView setSearchResults: searchResults];
    }
}

【问题讨论】:

  • 首先你能否记录下 searchText 和 searchResults 以确保问题出在 filterContentForSearchText 方法中,尤其是 filtersArrayUsingPredicate 方法中?
  • searchText 和 filterContentForSearchText 附加到 uiTableView 内的 SearchBar,而不是 UiPickerView。实际的 SearchBar 工作得很好:) 这是在单击我的“开始”按钮时使用 UiPickerView 组件过滤 uitableview 根本不起作用。

标签: objective-c uitableview view xcode4.5 uipickerview


【解决方案1】:

非常令人费解,您的代码实际上对我来说似乎没问题。我会在searchResults = [Strains filteredArrayUsingPredicate:resultPredicate]; 行被触发后立即从 NSLoging searchResults 开始,以防表视图代表中发生有趣的事情。

您还应该查看免费的 Sensible TableView 框架,因为它为您的数据提供了自动搜索和过滤功能。应该可以为您节省大量时间。

【讨论】:

  • *注意:我的 TableView 中肯定发生了一些有趣的事情。所以我 NSlogged 它,像这样: if (tableView == self.searchDisplayController.searchResultsTableView) { NSLog(@"Using the search results"); cell.titleLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:@"Title"];在完整列表中,我使用了: } else { NSLog(@"Using the FULL LIST!!"); cell.titleLabel.text = [[菌株 objectAtIndex:indexPath.row] objectForKey:@"Title"];控制台说它正在使用完整列表!啊。如何让它使用正确的视图?请参阅上面更新的代码。
【解决方案2】:

您的 Strains 数组似乎包含字典。所以你应该决定你想要过滤什么键,例如标题键,而不是使用SELF

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

从pickerViewController,你需要回到tableViewController。您可以使用委托。并尝试在表格视图控制器中创建一个单独的函数来过滤包含谓词的内容:

- (void)filterContentForPicker:(NSString*)searchText
{
    NSPredicate *resultPredicate = [NSPredicate
                                    predicateWithFormat:@"Title contains[cd] %@",
                                    searchText];

    searchResults = [Strains filteredArrayUsingPredicate:resultPredicate];
    [self.tableView reloadData]
}

【讨论】:

  • 我没有使用 searchText 进行过滤,我使用的是选定的 Pickerview 组件?我确实选择了每个组件过滤哪些键?
  • 然后从你的选择器视图didSelectRow你需要调用filterContentForSearchText方法。
  • 如果我将该方法放入pickerview,我将如何更改此代码以使其工作,因为它不使用搜索栏? -(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString { [self filterContentForSearchText:searchString scope:[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]];返回是;}
  • 您不应该将方法复制到选择器视图,而是选择器视图应将选定的选项传递给表视图控制器,表视图控制器应根据传递的选项过滤行。
  • 我明白了;所以我错过了pickerview将选定值传递给表视图控制器的位。你能告诉我那个代码是什么样子的吗?以前从来没有遇到过这个lol。非常感谢您的帮助,这让我很难受! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-16
  • 1970-01-01
  • 2011-12-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多