奇怪的UISearchDisplayController与隐藏键盘崩溃

时间:2012-03-25 18:46:14

标签: iphone objective-c ios uisearchbar uisearchdisplaycontroller

我有一个带有UISearchDisplayController的IUSearchBar,一切运行良好:

  • 当我触摸搜索栏时,键盘出现,TableView上有黑色封面,我可以开始输入

screenshot 1 http://joeranbosma.nl/xcode/sdc1.png

  • 当我输入内容时,会出现清除按钮(x),我的搜索结果也会出现。

screenshot 1 http://joeranbosma.nl/xcode/sdc2.png

  • 这一切都很棒。当我点击清除(x)按钮时,它只返回第一个屏幕截图状态(空搜索栏,结果上方有一个黑框)

但是,来了!

  • 当我输入内容然后移动搜索结果时,键盘隐藏(标准的UISearchDisplayController事物) 像这样:

screenshot 1 http://joeranbosma.nl/xcode/sdc3.png

当我然后点击clear(x)按钮时,程序崩溃并出现SIGABRT错误:

screenshot 1 http://joeranbosma.nl/xcode/sdc4.png

..我不知道如何解决这个问题:(

这是我的源代码:(不知道你需要解决什么问题) http://joeranbosma.nl/xcode/wearch_stack.zip

但我认为这是最有用的部分:

- (void)viewDidLoad {
    [super viewDidLoad];

    //Initialize the array.
    listOfItems = [[NSMutableArray alloc] init];
    copyListOfItems = [[NSMutableArray alloc] init];
    staticlist = [[NSMutableArray alloc] init];

    staticlist = listOfItems;

    //Add items
    [listOfItems addObject:@"Iceland"];
    [listOfItems addObject:@"Greenland"];
    [listOfItems addObject:@"Switzerland"];
    [listOfItems addObject:@"Norway"];
    [listOfItems addObject:@"New Zealand"];
    [listOfItems addObject:@"Greece"];
    [listOfItems addObject:@"Rome"];
    [listOfItems addObject:@"Ireland"];

    //Set the title
    self.navigationItem.title = @"Wearch";

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
   return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (searching)
        return [copyListOfItems count];
    else {
        return [listOfItems count];
    }
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

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

    // Configure the cell.
    if(searching)
        cell.textLabel.text = [copyListOfItems objectAtIndex:indexPath.row];
    else {
        NSString *txtLbl = [listOfItems objectAtIndex:indexPath.row];
        cell.textLabel.text = [txtLbl stringByAppendingString:@"x"];
    }

    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    //Get the selected word

    NSString *selectedWord = nil;

    if(searching)
        selectedWord = [copyListOfItems objectAtIndex:indexPath.row];
    else {
        selectedWord = [listOfItems objectAtIndex:indexPath.row];
    }

    //Initialize the detail view controller and display it.
    DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:@"DetailView" bundle:[NSBundle mainBundle]];
    dvController.selectedWord = selectedWord;
    [self.navigationController pushViewController:dvController animated:YES];
    [dvController release];
    dvController = nil;  
}
- (void) searchBarTextDidBeginEditing:(UISearchBar *)theSearchBar {
    searching = YES;
}
- (void)searchBar:(UISearchBar *)theSearchBar textDidChange:(NSString *)searchText {
    //Remove all objects first.
    [copyListOfItems removeAllObjects];

    if([searchText length] > 0) {
        searching = YES;
        [self searchTableView];
    }
    else {
        searching = NO;
    }

    [self.tableView reloadData];
}
- (void) searchBarSearchButtonClicked:(UISearchBar *)theSearchBar {
    [self searchTableView];
}
- (void) searchTableView {

    NSString *searchText = searchBar.text;
    NSMutableArray *searchArray = [[NSMutableArray alloc] init];

    NSMutableArray *results1 = [[NSMutableArray alloc] init];
    NSMutableArray *results2 = [[NSMutableArray alloc] init];

    [searchArray addObjectsFromArray:listOfItems];

    for (NSString *sTemp in searchArray) {
        NSRange titleResultsRange = [sTemp rangeOfString:searchText options:NSCaseInsensitiveSearch];

        if (titleResultsRange.length > 0){
            if (titleResultsRange.location == 0) {
                [results1 addObject:sTemp];
            }
            else{
                [results2 addObject:sTemp];
            }
        }
    }

    for (NSString *sTemp in results1) {
        [copyListOfItems addObject:sTemp];
    }
    for (NSString *sTemp in results2) {
        [copyListOfItems addObject:sTemp];
    }

    [searchArray release];
    searchArray = nil;
}

我希望你们中的一个能解决这个问题。

你能说出你喜欢的图片吗?

1 个答案:

答案 0 :(得分:4)

这是一个有趣的问题。答案很长,searchBarTextDidBeginEditing:tableView:numberOfRowsInSection:之后tableView:cellForRowAtIndexPath:之前被调用。结果是tableView期望[listOfItems count]行数,但是当它调用tableView:cellForRowAtIndexPath:时,searching BOOL为YES,因此视图控制器使用{ {1}}填充表格,当然不包含足够数量的对象来填充表格。

简短的回答是,在您搜索之前,停止告诉您正在搜索的视图控制器;如果您使用实际文本进行搜索,请设置copyListOfItems,而不仅仅是searching = YES;是第一响应者。

真正简短的回答:

searchBar

似乎工作正常。

针对此类情景的一些提示:

1)查看控制台中的打印堆栈跟踪。它会让你看到问题是:

- (void) searchBarTextDidBeginEditing:(UISearchBar *)theSearchBar {
    // Comment this assignment out
    //searching = YES;
}

2)大量使用'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array' ;我发现最有帮助的是:

NSLog

编辑响应控制台中的非符号化堆栈跟踪(即NSLog(@"%@",NSStringFromSelector(_cmd)); ):

3)使用异常断点;如图所示:

enter image description here

4)添加未捕获的异常处理程序; As described here