2

これを行うと、アプリがクラッシュします。

  1. UITableView で検索を行います

  2. 検索後、UITableView のsearchDisplayControllerUITableViewCell をタップし、別の View Controller に移動します

  3. 次に、メインの UITableView (questionTable検索したもの) に戻り、最後のセル、または以前の検索結果の数よりも大きいセルをタップします。

  4. 次のエラーでアプリがクラッシュします。

    *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 12 beyond bounds [0 .. 0]'
    *** First throw call stack:(0x35aa188f 0x37e48259 0x359ea9db 0x155fd 0x3384df5b 0x153ed 0x3358793d 0x33601627 0x355bb933 0x35a75a33 0x35a75699 0x35a7426f 0x359f74a5 0x359f736d 0x37693439 0x33503cd5 0x95a3 0x9548) terminate called throwing an exception(lldb) 
    

UITableView の検索は私にとって新しいトピックであるため、問題は私のコードにあると思われます。それが私がそれを行う方法です:

1.私の VC はこれらのプロトコルに準拠しています<UITableViewDataSource, UITableViewDelegate, UISearchDisplayDelegate, UISearchBarDelegate>

2.次の変数があります。

@property (nonatomic, retain) NSMutableArray *searchResults;
@property (nonatomic, copy) NSString *savedSearchTerm;

3.viewDidLoad検索する UITableView のソースをセットアップします。

    self.questionList = [[NSArray alloc]
                     initWithObjects: MY OBJECTS HERE, nil];

if ([self savedSearchTerm])
{
    [[[self searchDisplayController] searchBar] setText:[self savedSearchTerm]];
}

4. 検索を処理するために、次のアクションがあります。

- (void)handleSearchForTerm:(NSString *)searchTerm
{
[self setSavedSearchTerm:searchTerm];

if ([self searchResults] == nil)
{
    NSMutableArray *array = [[NSMutableArray alloc] init];
    [self setSearchResults:array];
}
[[self searchResults] removeAllObjects];

if ([[self savedSearchTerm] length] != 0)
{
    for (NSString *currentString in [self questionList])
    {
        if ([currentString rangeOfString:searchTerm options:NSCaseInsensitiveSearch].location != NSNotFound)
        {
            [[self searchResults] addObject:currentString];
        }
    }
}   
}

5) UITable ビューの設定方法は次のとおりです。

    (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    {
    NSInteger row = [indexPath row];
    NSString *contentForThisRow = nil;

    if (tableView == [[self searchDisplayController] searchResultsTableView])
        contentForThisRow = [[self searchResults] objectAtIndex:row];
    else
        contentForThisRow = [[self questionList] objectAtIndex:row];

    static NSString *CellIdentifier = @"questionsCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }
    [[cell textLabel] setText:contentForThisRow];
    return cell;
    }

6)私のnumberOfRowsInSection方法は次のようになります。

(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger rows;

if (tableView == [[self searchDisplayController] searchResultsTableView])
rows = [[self searchResults] count];
else
rows = [[self questionList] count];
return rows;
}

7) 最後に、次の 2 つの方法があります。

(BOOL)searchDisplayController:(UISearchDisplayController *)controller 
shouldReloadTableForSearchString:(NSString *)searchString
{
    [self handleSearchForTerm:searchString];
    // Return YES to cause the search result table view to be reloaded.
    return YES;
}

(void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller
{
    [self setSavedSearchTerm:nil];
    [[self questionTable] reloadData];
}

長い質問で本当に申し訳ありません。コードに間違いがありました。誰かがこれを行う正しい方法を教えてくれることを願っています。Search Bar Controller は IB で適切にリンクされています。

新しい編集: 新しい VC をプッシュしていdidSelectRowAtIndePathます:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [self performSegueWithIdentifier:@"toAnswer" sender:indexPath];
}

そして、そこで NSString を更新しています。TableViewを1つだけ使用した場合、完全に機能しました

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    ((QandADetailsViewController *)segue.destinationViewController).delegate=self;

    NSIndexPath *indexPath = (NSIndexPath *)sender;

    QandADetailsViewController *mdvc = segue.destinationViewController;

    if (self.searchResults == nil) {
        mdvc.questionName = [self.questionList
                             objectAtIndex:indexPath.row];
    } else {
        mdvc.questionName = [self.searchResults
                             objectAtIndex:indexPath.row];
    }
}
4

2 に答える 2

3

セグエの準備で、searchResults == nil のチェックが間違っている可能性があります。最初の検索の後、それが nil になると期待する理由はありません。つまり、後続のテーブル選択で常に検索配列を逆参照し、インデックスが範囲外であることを説明します。

if ([self.searchDisplayController isActive])解決策は、検索結果が存在するかどうかを尋ねることだと思います。

于 2012-08-24T14:08:36.587 に答える
1

配列が空のようです。

配列が空になる場所を確認できるように、すべてのステップの後に配列をログに記録することをお勧めします。

行番号とメソッド名もログに記録します。これを参照してください。ログの作成方法:

NSLog(@"%s\n [Line: %d]\n  array:%@\n\n", __PRETTY_FUNCTION__, __LINE__, yourArray);
于 2012-08-24T08:00:38.920 に答える