UISearchBar取消按钮崩溃

时间:2011-02-07 09:51:29

标签: iphone xcode user-interface

我有一个UITableView,在didSelectRowAtIndexPath上推送另一个UITableView进行搜索......

    LocationSearchViewController *locationSearchViewController = [[LocationSearchViewController alloc] initWithNibName:@"LocationSearchViewController"  bundle:nil];
    locationSearchViewController.delegate = self;       
    UITableViewCell *cell = [myTableView cellForRowAtIndexPath:indexPath];
    locationSearchViewController.defaultLocation = cell.detailTextLabel.text;

    [[self navigationController]  pushViewController:locationSearchViewController animated:YES];
    [locationSearchViewController release];

搜索视图包含一个UISearchBar,并启用了取消按钮。如果用户点击取消按钮,应用程序将崩溃并显示objc_exception_throw。控制台显示......

  

2011-02-06 22:05:43.960 JetLogger [2381:207] * 断言失败 - [UISearchDisplayController setActive:animated:],/ SourceCache / UIKit_Sim / UIKit-1447.6.4 / UISearchDisplayController.m:589

但是,如果用户点击表格视图中的项目(搜索结果),我将关闭搜索视图,并且没有崩溃。我不明白为什么差异,因为我用相同的代码弹出搜索视图...

在LocationSearchViewController ...

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
   if ([self.delegate respondsToSelector:@selector(locationSearchViewDidDismiss:withLocation:)]) {
    [self.delegate locationSearchViewDidDismiss:self withLocation:[tableView cellForRowAtIndexPath:indexPath].textLabel.text];
   }
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar{
   if ([self.delegate respondsToSelector:@selector(locationSearchViewDidDismiss:withLocation:)]) {
     [self.delegate locationSearchViewDidDismiss:self withLocation:@"No results found"];
   }
}

在代表......

- (void)locationSearchViewDidDismiss:(LocationSearchViewController *)controller withLocation:(NSString*)location{   
   if((location != @"") && (location != @"No results found")){
    //update the table data
    [myTableView reloadData];
   }
   [self.navigationController popViewControllerAnimated:YES];
}

感谢任何帮助。

约翰

6 个答案:

答案 0 :(得分:6)

因为我们弹出viewController,搜索栏会失去焦点。这会导致调用setActive,但在发生这种情况时,搜索栏已全部解除分配。所以我们需要在弹出之前将active设置为no。

因此,一个简单的解决方法是:

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
    [self.searchDisplayController setActive:NO animated:NO];
    [self.navigationController popViewControllerAnimated:YES]; 
}

答案 1 :(得分:3)

我遇到了同样的问题。 XCode 4 IOS 4.3

对我而言,问题仅在焦点位于搜索栏内时 我发现了一些可能有用的解决方法。

以下是代码:

static BOOL _cancelBtnClicked = NO;

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar{
    Log(@"Enter"); 
    if(searchDisplayController.active){
        _cancelBtnClicked = YES;
    }else{
        [self back];
    }
}

- (void)searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller{
    Log(@"Enter");
    if(_cancelBtnClicked){
        _cancelBtnClicked = NO;
        [self back];
    }
}

-(void)back{
[self.navigationController popViewControllerAnimated:YES];
}

答案 2 :(得分:3)

我认为提供的答案是不完美的,因为它们间接解决了问题,即在释放的代理上调用searchDisplayControllerDidEndSearch:。致电[self.searchDisplayController setActive:NO animated:NO]可能会在searchBarCancelButtonClicked:内工作,但会在其他地方失效,例如在searchBarTextDidEndEditing:内。

相反,只需在弹出控制器之前直接清除代理: self.searchDisplayController.delegate = nil;

这将确保不会在解除分配的实例上调用委托方法。

答案 3 :(得分:0)

我刚遇到这个问题。

当我解除包含popViewControllerAnimated搜索内容的viewcontroller时出现此错误。如果您以模态方式呈现相同的viewcontroller,并使用modal dismiss函数关闭,则此断言也不会触发。

要解决此问题,我必须添加(使用您的代码作为示例)

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar{
   [self.searchController setActive:NO animated:NO];
   if ([self.delegate respondsToSelector:@selector(locationSearchViewDidDismiss:withLocation:)]) {
     [self.delegate locationSearchViewDidDismiss:self withLocation:@"No results found"];
   }
}

这样,searchcontroller在调用它想要的任何内部函数之前是不活动的。感觉这是一个4.2 sdk的错误,但是我需要用新的4.3克种子来检查这个。

您是否找到了其他解决方案?

我宁愿不使用上面的修复,因为解雇动画有点难看:\

答案 4 :(得分:0)

我遇到了同样的问题。

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
    [self.searchDisplayController setActive:NO animated:NO];
    [self.navigationController popViewControllerAnimated:YES]; 
}

在我的情况下没有解决它。相反,我在另一个地方调用[self.searchDisplayController setActive:NO animated:NO],使之前被调用。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // ....

    [self.searchDisplayController setActive:NO animated:NO];
}

答案 5 :(得分:0)

Swift Edition

func searchBarCancelButtonClicked(searchBar: UISearchBar) {
    self.searchDisplayController?.active = false
    self.dismissViewControllerAnimated(true, completion: nil)
}