1

ユーザーが実行した検索から UITableView に結果を表示しようとすると、以下のエラーが発生します。以下のコードは検索、フィルタリングを行っており、結果を表示する必要があります。(しかしそうではない)

@implementation ProductsViewController

{
    NSPredicate *searchSearch;
    NSArray *results;
}

@synthesize bakeryTableView, bakeryProductArray, searchResults, itemName;

-(void)viewDidLoad
{
    bakeryProductArray = [[NSMutableArray alloc]init];
    searchResults = [[NSArray alloc]init];
    [self testermethod];
    [[self navigationController] setNavigationBarHidden:NO];
    [super viewDidLoad];
}

-(void)testermethod
{
    PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];
    // Retrieve the top songs by sales
    [query orderByAscending:@"Name"];

    // Limit to retrieving ten songs
    query.limit = 100;
    [query findObjectsInBackgroundWithBlock:^(NSArray *food, NSError *error) {
        if (error) return;

        // Songs now contains the last ten songs, and the band field has
        // been populated. For example:
        for (PFObject *song in food) {

            PFObject *simple = [song objectForKey:@"Name"];

            [bakeryProductArray addObject: simple];
        }
        [bakeryTableView reloadData];
        return;
        NSLog(@"Passed");
    }];
}


-(id)initWithCoder:(NSCoder *)aCoder {
    self = [super initWithCoder:aCoder];
    if (self) {
        self.parseClassName = @"JackiesBakeryProducts";
        self.textKey = @"objectid";
        self.pullToRefreshEnabled = YES;
        self.paginationEnabled = NO;
       // self.objectsPerPage = 20;
    }

    return self;
}

-(PFQuery *)queryForTable
{
    PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];

    // If no objects are loaded in memory, we look to the cache first to fill the table
    // and then subsequently do a query against the network.
    if ([self.objects count] == 0) {
        query.cachePolicy = kPFCachePolicyCacheThenNetwork;
    }

    [query orderByAscending:@"Name"];

    return query;
}


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

    //Fill table in with data
    static NSString *cellIdentifier = @"Cell";
    PFObject *selectedObject = [self objectAtIndexPath:indexPath];
    NSLog(@"%@", selectedObject);
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
    }

    if (tableView == self.searchDisplayController.searchResultsTableView) {

            NSString *selectedObject = [searchResults objectAtIndex:indexPath.row];
            NSLog(@"%i", searchResults.count);
            cell.textLabel.text = selectedObject;
        }

    else {

        NSString *productName = [selectedObject objectForKey:@"Name"];
        NSString *productQuantity = [selectedObject objectForKey:@"Quantity"];

        cell.textLabel.text = productName;
        cell.detailTextLabel.text = productQuantity;
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    }

    return cell;
}

#pragma mark - UITableView Delegate methods

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    //Deal with user search from tableview
    if (bakeryTableView == self.searchDisplayController.searchResultsTableView)
    {

        [self performSegueWithIdentifier: @"bakeryDetails" sender:self];

    }

    //Prep the next view controller with data from current view (data passing)
    detailedViewController *productinfo = [self.storyboard instantiateViewControllerWithIdentifier:@"bakeryDetails"];

    PFObject *selectedObject = [self objectAtIndexPath:indexPath];

    productinfo.productName = [selectedObject objectForKey:@"Name"];
    productinfo.productImage = [selectedObject objectForKey:@"ImageUrl"];
    productinfo.productDescription = [selectedObject objectForKey:@"Description"];
    productinfo.productPrice = [selectedObject objectForKey:@"Price"];
    productinfo.productQuantity = [selectedObject objectForKey:@"Quantity"];
    productinfo.productAllergy = [selectedObject objectForKey:@"Allergy"];

    [self.navigationController pushViewController:productinfo animated:YES];
    [bakeryTableView deselectRowAtIndexPath:indexPath animated:YES];

}


//Becareful here as wrong predicateWithFormat can crash app on keying in search
-(void)filterContentForSearchText:(NSString *)searchText scope:(NSString *)scope
{

    searchSearch = [NSPredicate predicateWithFormat:@"self CONTAINS[cd] %@",searchText];
    searchResults = [bakeryProductArray filteredArrayUsingPredicate:searchSearch];

    NSLog(@"Filtered Food Product Count --> %d",[searchResults count]);
    NSLog(@"%@", searchResults);
}


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

}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Check to see whether the normal table or search results table is being displayed and return the count from the appropriate array
    if (tableView == self.searchDisplayController.searchResultsTableView)
    {
        return [searchResults count];
    }
    else
    {
        return [bakeryProductArray count];
    }
}

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


@end

上記のコードで。* Terminating app due to uncaught exception 'NSRangeException', reason: '* -[__NSArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]'でエラーが生成されます(入力された最初の文字で検索が機能します)しかし、2番目でクラッシュします)

index.rowごとに呼び出されたときにNSArrayが正しく機能していないという大まかな考えがあります。しかし、これを克服する方法がわかりません。

@try - catch ステートメントを使用して、searchResults で何が起こっているかを報告しました。これを生み出した

2013-09-08 13:27:20.876 jackies[995:c07] Filtered Food Product Count --> 1
2013-09-08 13:27:20.876 jackies[995:c07] Aero
2013-09-08 13:27:20.877 jackies[995:c07] Caught this (
    Aero
)
2013-09-08 13:27:20.877 jackies[995:c07] Caught this (
    Aero
)
2013-09-08 13:27:20.877 jackies[995:c07] Caught this (
    Aero
)
2013-09-08 13:27:20.877 jackies[995:c07] Caught this (
    Aero
)
2013-09-08 13:27:20.877 jackies[995:c07] Caught this (
    Aero
)
2013-09-08 13:27:20.877 jackies[995:c07] Caught this (
    Aero
)
2013-09-08 13:27:20.878 jackies[995:c07] Caught this (
    Aero
)
2013-09-08 13:27:20.878 jackies[995:c07] Caught this (
    Aero
)
2013-09-08 13:27:32.550 jackies[995:c07] Filtered Food Product Count --> 1
2013-09-08 13:27:32.551 jackies[995:c07] Aero
2013-09-08 13:27:32.551 jackies[995:c07] Caught this (
    Aero
)
2013-09-08 13:27:32.551 jackies[995:c07] Caught this (
    Aero
)
2013-09-08 13:27:32.551 jackies[995:c07] Caught this (
    Aero
)
2013-09-08 13:27:32.552 jackies[995:c07] Caught this (
    Aero
)
2013-09-08 13:27:32.552 jackies[995:c07] Caught this (
    Aero
)
2013-09-08 13:27:32.552 jackies[995:c07] Caught this (
    Aero
)
2013-09-08 13:27:32.552 jackies[995:c07] Caught this (
    Aero
)
2013-09-08 13:27:32.552 jackies[995:c07] Caught this (
    Aero
)
2013-09-08 13:27:34.188 jackies[995:c07] Filtered Food Product Count --> 1
2013-09-08 13:27:34.189 jackies[995:c07] Aero
2013-09-08 13:27:34.189 jackies[995:c07] Caught this (
    Aero
)
2013-09-08 13:27:34.189 jackies[995:c07] Caught this (
    Aero
)
2013-09-08 13:27:34.189 jackies[995:c07] Caught this (
    Aero
)
2013-09-08 13:27:34.189 jackies[995:c07] Caught this (
    Aero
)
2013-09-08 13:27:34.189 jackies[995:c07] Caught this (
    Aero
)
2013-09-08 13:27:34.190 jackies[995:c07] Caught this (
    Aero
)
2013-09-08 13:27:34.190 jackies[995:c07] Caught this (
    Aero
)
2013-09-08 13:27:34.190 jackies[995:c07] Caught this (
    Aero
)

どんな助けでも素晴らしいでしょう。

4

2 に答える 2

1

配列に辞書が含まれている場合、述語は間違っています。bakeryProductArray辞書ではなく、文字列の配列があればうまくいきます。それ以外の場合は、使用する必要があります

@"name CONTAINS[cd] %@"

フォーマット文字列として。

また、検索結果の配列に基づいてテーブルをリロードしてください。つまり、データソース メソッドをチェックして、正しい行数を返すようにしてください。

2 つ目のポイント: 2 つのテーブルを区別する前に、表示したいオブジェクトを取得するのは論理的ではないようです。ロジックは次のようになります。

UITableViewCell *cell = // dequeue cell
if (tableView == self.searchDisplayController.searchResultsTableView) {
  // retrieve object at IndexPath.row
  // configure the cell to display it
}
else { 
  // do the same for main table view
}
return cell;
于 2013-09-07T22:33:32.433 に答える
0

試行錯誤で問題を解決しました。

メソッドも欠落していた

  • (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { // 通常のテーブルまたは検索結果テーブルが表示されているかどうかを確認し、適切な配列からカウントを返す場合 (tableView == self.searchDisplayController. searchResultsTableView) { return [searchResults count]; } else { return [bakeryProductArray カウント]; } }
于 2013-09-08T16:27:46.940 に答える