如下图所示,当我点击搜索字段时,我的UISearchBar会调整大小.它动画很好地覆盖了导航栏,然后弹出……它缩小了.
设置
UISearchBar位于一个vanilla UIView中,设置为tableHeaderView.我正在使用UIView(而不是将UISearchBar设置为标头),因为我想在标头中添加其他视图.
视图在XIB文件中定义,UISearchBar锚定到其所有边框.这些限制似乎并不重要;如果我删除它们,会发生同样的问题.
实验
检查Reveal中的视图层次结构告诉我UIView具有正确的大小,当发生这种情况时,UISearchBar的宽度为1(?!).
作为一个实验,我将UISearchBar子类化,并使intrinsicContentSize返回{320,44}.有了这个,UISearchBar显示正常,但是当我按下取消时,我得到以下异常:
*** Assertion failure in -[UITableView layoutSublayersOfLayer:],/SourceCache/UIKit_Sim/UIKit-2903.23/UIView.m:8540 *** Terminating app due to uncaught exception 'NSInternalInconsistencyException',reason: 'Auto Layout still required after executing -layoutSubviews. UITableView's implementation of -layoutSubviews needs to call super.'
_headerView = [[UIView alloc] initWithFrame:CGRectMake(0,self.view.bounds.size.width,44)]; UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0,44)]; searchBar.delegate = self; [_headerView addSubview:searchBar]; _searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self]; _searchDisplayController.searchResultsDelegate = self; _searchDisplayController.searchResultsDataSource = self; _searchDisplayController.delegate = self; _tableView.tableViewHeader = _headerView;
这里发生了什么?我显然不会再使用笔尖与UISearchBar一起工作,但我想了解到底发生了什么.
解决方法
区别在于translatesAutoresizingMaskIntoConstraints的搜索栏值.对于基于XIB的视图,默认值为NO,对于基于代码的视图,默认值为YES.显然,搜索控制器假定值为YES,并且在移植搜索栏时不会设置任何显式约束.
在代码中将值设置为YES应该修复它(在本地验证).
UPDATE
如注释中所述,即使使用translatesAutoresizingMaskIntoConstraints = YES,控制器也不会在取消时将标题视图恢复为其原始状态.但似乎确实存在一种解决方法.您可以在标题视图中创建一个插座,并在searchDisplayControllerDidEndSearch中自行恢复.我做了一个粗略的概念验证(并更新了我的示例项目):
- (void)searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller { self.tableView.tableHeaderView = self.headerView; [self.searchBar removeFromSuperview]; self.searchBar.frame = CGRectMake(0,20,320,44); [self.headerView addSubview:self.searchBar]; }