0

現在、このチュートリアルに従って検索を実装しようとしています。 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でそれを行うことです..だから私の配列は毎回同じ値をロードし、検索しますテーブルは「再作成」されます。異なる項目である場合にのみ、データを配列にロードする方法を見つける必要があります。

4

1 に答える 1

0

最後に、何が悪いのかわかりました。json レスポンスの name フィールドを配列に保存していました。私の配列はcellForRowAtIndexPathで更新されていたので、検索ボックスに2文字を入力した後、結果と一致し、その結果は配列に2回保存されました(したがって、配列に2つの同じアイテムがありました)。したがって、インデックスが範囲外だったためにクラッシュしました.

配列に同じ値が含まれているかどうかを確認し、一意の値をこのような別の配列に保存することで修復しました。

newarray = [[NSMutableArray alloc] init];
    NSString *laststring = nil;
    for (NSString *currentstring in poleMien)
    {
        if (![currentstring isEqualToString:laststring]) [newarray addObject:currentstring];
        laststring = currentstring;
    }

eyebrowsoffire に感謝します、あなたは私に正しい道を示してくれました :)

于 2012-11-21T13:54:02.777 に答える