【问题标题】:Strange UISearchDisplayController Crash with hidden keyboard带有隐藏键盘的奇怪 UISearchDisplayController 崩溃
【发布时间】:2013-11-20 03:29:32
【问题描述】:

我有一个带有 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

当我然后单击清除 (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;
}

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

你也可以说你喜欢这些图片吗?

【问题讨论】:

    标签: iphone objective-c ios uisearchbar uisearchdisplaycontroller


    【解决方案1】:

    这是一个有趣的问题。长答案是searchBarTextDidBeginEditing:tableView:numberOfRowsInSection: 之后但在tableView:cellForRowAtIndexPath: 之前被调用。结果是tableView 期待[listOfItems count] 的行数,但是当它调用tableView:cellForRowAtIndexPath: 时,searching BOOL 是YES 所以视图控制器使用copyListOfItems 来填充表格,这当然是没有足够数量的对象来填充表格。

    简短的回答是,在你搜索之前不要告诉视图控制器你正在搜索;设置searching = YES; 时,不仅是当searchBar 是第一响应者时,而是在您用于搜索的实际文本时。

    真正简短的答案:

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

    它似乎工作正常。

    针对这种情况的一些提示:

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

    'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'
    

    2) 大量使用NSLogs;我觉得最有帮助的是:

    NSLog(@"%@",NSStringFromSelector(_cmd));
    

    编辑响应控制台中的非符号化堆栈跟踪(即0x14d3ec9 0x36e5c2):

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

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

    【讨论】:

    • 哇,非常感谢!这确实是问题所在。但是,除了你发现了问题,我现在对语言理解得更好了。 And I never looked at the console because the was a lot of this: '422af1 0x14d3ec9 0x36e5c2 0x36e55a 0x413b76 0x41403f 0x4132fe 0x393a30 0x393c56 0x37a384 0x36daa9 0x1bc8fa9 0x14a61c5 0x140b022 0x140990a 0x1408db4 0x1408ccb 0x1bc7879 0x1bc793e 0x36ba9b 0x256d 0x24e5)' And I just didn't knew there was something有用,所以我没有进一步查看。所以:非常感谢!
    • 很高兴为您提供帮助,尤其是想了解更多信息的人。因此,我添加了一些提示来帮助您处理您提到的无用的十六进制堆栈跟踪。
    • 我的应用程序确实向上 :)
    猜你喜欢
    • 2016-10-19
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 2016-09-14
    • 1970-01-01
    • 2013-11-16
    • 2019-03-21
    相关资源
    最近更新 更多