0

我在我的 UITableView 上实现 UISearchBarDelegate 时遇到问题,每次我尝试在 UITableView 中搜索某些内容时,它要么不显示所需的结果,要么导致应用程序崩溃并显示错误消息:

由于未捕获的异常“NSRangeException”而终止应用程序,原因:“*** -[__NSArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]”

这是我的头文件里面:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, UISearchDisplayDelegate, UISearchBarDelegate>
{
    UITableView *mainTableView;

    NSMutableArray *contentsList;
    NSMutableArray *searchResults;
    NSString *savedSearchTerm;

    NSMutableArray *ivSectionKeys;
    NSMutableDictionary *ivSectionContents;
}

@property (nonatomic, retain) IBOutlet UITableView *mainTableView;
@property (nonatomic, retain) NSMutableArray *contentsList;
@property (nonatomic, retain) NSMutableArray *searchResults;
@property (nonatomic, copy) NSString *savedSearchTerm;

@property (nonatomic, retain) NSMutableArray *sectionKeys;
@property (nonatomic, retain) NSMutableDictionary *sectionContents;

- (void)handleSearchForTerm:(NSString *)searchTerm;

@end

虽然这是在我的实现文件中:

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

@synthesize mainTableView;
@synthesize contentsList;
@synthesize searchResults;
@synthesize savedSearchTerm;

@synthesize sectionKeys = ivSectionKeys;
@synthesize sectionContents = ivSectionContents;

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    NSMutableArray *keys = [[NSMutableArray alloc] init];
    NSMutableDictionary *contents = [[NSMutableDictionary alloc] init];

    NSString *colorKey = @"Colors";
    NSString *clothingKey = @"Clothing";
    NSString *miscKey = @"Misc";

    [contents setObject:[NSArray arrayWithObjects:@"Red", @"Blue", nil] forKey:colorKey];
    [contents setObject:[NSArray arrayWithObjects:@"Pants", @"Shirt", @"Socks", nil] forKey:clothingKey];
    [contents setObject:[NSArray arrayWithObjects:@"Wankle Rotary Engine", nil] forKey:miscKey];

    [keys addObject:clothingKey];
    [keys addObject:miscKey];
    [keys addObject:colorKey];

    self.sectionKeys = keys;
    self.sectionContents = contents;

    // Restore search term
    if (self.savedSearchTerm)
    {
        self.searchDisplayController.searchBar.text = self.savedSearchTerm;
    }
}

- (void)viewDidUnload
{
    [super viewDidUnload];

    // Save the state of the search UI so that it can be restored if the view is re-created.
    self.savedSearchTerm = self.searchDisplayController.searchBar.text;

    self.searchResults = nil;
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [self.mainTableView reloadData];
}

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

- (void)handleSearchForTerm:(NSString *)searchTerm
{
    self.savedSearchTerm = searchTerm;

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

    [self.searchResults removeAllObjects];

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

#pragma mark -
#pragma mark UITableViewDataSource Methods

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    NSInteger sections = [self.sectionKeys count];

    return sections;
}

- (NSString *)tableView:(UITableView *)tableView
titleForHeaderInSection:(NSInteger)section
{
    NSString *key = [self.sectionKeys objectAtIndex:section];

    return key;
}

- (NSInteger)tableView:(UITableView *)tableView
 numberOfRowsInSection:(NSInteger)section
{
    NSString *key = [self.sectionKeys objectAtIndex:section];
    NSArray *contents = [self.sectionContents objectForKey:key];

    NSInteger rows;

    if (tableView == [[self searchDisplayController] searchResultsTableView])
        rows = [self.searchResults count];
    else
        rows = [contents count];

    NSLog(@"rows is: %d", rows);

    return rows;
}

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *key = [self.sectionKeys objectAtIndex:indexPath.section];
    NSArray *contents = [self.sectionContents objectForKey:key];
    NSString *contentForThisRow = [contents objectAtIndex:indexPath.row];

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

    static NSString *CellIdentifier = @"CellIdentifier";

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

    cell.textLabel.text = contentForThisRow;

    return cell;
}

#pragma mark -
#pragma mark UITableViewDelegate Methods

- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
}

#pragma mark -
#pragma mark UISearchDisplayController Delegate Methods

- (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.savedSearchTerm = nil;

    [self.mainTableView reloadData];
}

@end

我认为我的问题在我的 for 循环中,但我不太确定。

4

1 回答 1

0

您需要更新所有表视图数据源和委托方法来处理这两个表(您只在某些情况下这样做):

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    NSInteger sections = [self.sectionKeys count];

    return sections;
}

应该:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    if (tableView == self.tableView) {
        NSInteger sections = [self.sectionKeys count];

        return sections;
    } else { // assume it's the search table
        // replace this with the actual result
        return numberOfSectionsForSearchTable;
    }
}
于 2012-11-10T19:17:08.380 回答