現在、このチュートリアルに従って検索を実装しようとしています。 http://www.appcoda.com/how-to-add-search-bar-uitableview/ ただし、アプリがクラッシュするところですが、修正方法がわかりません。
私のアプリに来るJSONには、現在1行のデータしかありません(dbアクセスがないため、変更できません)。
私の最初のビューはよさそうです。TableView が読み込まれます (1 行)。検索バーをタップして、そのアイテムの名前にない文字を入力すると、通常の「結果が見つかりません」という画面が表示されます。アイテムの名前に含まれる任意の文字を入力すると、フィルターされたアイテムが期待どおりに表示されます。ただし、アイテムの名前にある 2 番目の文字を入力すると、アプリがクラッシュし、コンソールに次の出力が表示されます。
Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFArray objectAtIndex:]: index (1) beyond bounds (1)'
今私のコードに。numberOfRowsInSection メソッドは、検索に応じて変更されます。
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
if (tableView == self.searchDisplayController.searchResultsTableView) {
return [searchResults count];
} else {
return [[resultSearch valueForKeyPath:@"data.auctions"]count];
}
}
numberOfSectionsInTableView にはハードコードされたセクションが 1 つだけあります (1 を返します。現在それ以上は必要ないため)。
今私の cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = @"SimpleTableItem";
SimpleTableCell *cell = (SimpleTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier]; //custom cell
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"SimpleTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
NSDictionary *aucdict = [jsonAukResultsSearch objectAtIndex:indexPath.row]; //assigning current row from NSMutableArray(jsonAukResultsSearch) to Dictionary, this is probably crash spot
NSURL *imageURL = [NSURL URLWithString:[aucdict objectForKey:@"img_url"]];
NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
//sending request to get picture
UIImage *imageLoad = [[UIImage alloc] initWithData:result];
NSString *timeString = [aucdict objectForKey:@"time_left"];
NSString *priceString = [aucdict objectForKey:@"current_value"];
// Configure the cell...
if (tableView == self.searchDisplayController.searchResultsTableView) {
cell.textLabel.text = [searchResults objectAtIndex:indexPath.row];
} else {
cell.nameLabel.text = [aucdict objectForKey:@"name"];
}
//cell.thumbnailImageView.image = imageLoad;
//commented while crashes are happening
return cell;
}
さて、私のアプリがクラッシュした後、私の行は
NSDictionary *aucdict = [jsonAukResultsSearch objectAtIndex:indexPath.row];
はハイライターなので、おそらくindexPathパラメーターが範囲外の場所だと思います。index(1)がbounds(1)を超える方法が本当にわかりません。私は、(検索フレーズに応じて)返される行が0または1しかないことを知っています。
私は今日検索を始めたばかりなので、それらのトリッキーなスポットが何であるかについての手がかりがありません..どんな提案も大歓迎です:) Yanchi、ありがとう
編集:わかりましたので、問題がどこにあるのかを見つけました...この質問の上部に記載されているチュートリアルに厳密に従っています..このメソッドは、検索結果を含む配列を返すことになっています。
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:@"SELF contains[cd] %@",
searchText];
searchResults = [poleMien filteredArrayUsingPredicate:resultPredicate];
NSLog(@"%u",[searchResults count]);
}
ご覧のとおり NSLog を追加しました...一致する最初の文字を追加すると、コンソール出力は (本来あるべき) 1 になるため、フィルタリングされた結果は問題なく表示されます。ただし、別の一致する文字を入力すると、searchResults 配列が 2 に増加し (「一致する」文字をカウントするかのように)、これがおそらくクラッシュする理由です (インデックス 1 にアクセスしようとすると、データは 1 つしかありません)。私のsearchResults配列のアイテム)
その後、配列の内容を表示するように NSLog を変更しました... 一致する文字を挿入した後、同じ項目が配列に追加されます (したがって、配列内の最初の項目と同じデータを持つ別の項目が配列内にあります)
編集2:わかりましたので、私の問題は、jsonデータを辞書から配列に保存するときはいつでも(配列を使用して結果をフィルタリングできるようにするため)、cellForRowAtIndexPathでそれを行うことです..だから私の配列は毎回同じ値をロードし、検索しますテーブルは「再作成」されます。異なる項目である場合にのみ、データを配列にロードする方法を見つける必要があります。