为什么这个UISearchBar得到调整?

如下所示,当我点击search字段时,我的UISearchBar被resize。 它很好地覆盖导航栏,然后popup…缩小。

设置

UISearchBar是在作为tableHeaderView设置的香草UIView里面。 我正在使用UIView (而不是将UISearchBar设置为标题),因为我想在标题中添加其他视图。

该视图是在XIB文件中定义的,并且UISearchBar被锚定到它的所有边界。 这些限制似乎并不重要。 如果我删除它们,也会发生同样的问题。

实验

在Reveal中检查视图层次告诉我, UIView具有正确的大小,当发生这种情况时, UISearchBar宽度为1( UISearchBar

作为一个实验,我将子类{320,44} UISearchBar ,并使intrinsicContentSize返回{320,44} 。 有了这个UISearchBar显示正确,但是当我按下取消,我得到以下exception:

  *** 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.' 

解决方法

如果我通过代码创build所有东西,它就可以工作。

 _headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 44)]; UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 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一起工作了,但是我想知道这是怎么回事。

不同的是在search栏的translatesAutoresizingMaskIntoConstraints的值。 它基于XIB的视图默认为NO ,基于代码的视图默认为YES 。 显然,search控制器的值为YES,并且在移植search栏时没有设置任何明确的约束条件。

在代码中将值设置为YES应该修复它(本地validation)。

UPDATE

如注释中所述,即使在translatesAutoresizingMaskIntoConstraints = YES ,控制器在取消时也不会将标题视图恢复到原始状态。 但似乎有一个解决方法。 您可以创build一个出口到您的标题视图,并在searchDisplayControllerDidEndSearchsearchDisplayControllerDidEndSearch恢复。 我做了一个粗略的概念certificate(并更新了我的示例项目):

 - (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]; } 

从@TimothyMoose和@hpique所说的关于设置翻译自动化的方法= YES(yuck)

在我的代码中,我发现,如果我做了以下显示searchDisplayController

 self.searchDisplayController.searchBar.translatesAutoresizingMaskIntoConstraints = YES [self.searchDisplayController setActive:YES animated:YES] 

在closuressearchDisplayController时做相反的事情,

 self.searchDisplayController.searchBar.translatesAutoresizingMaskIntoConstraints = NO [self.searchDisplayController setActive:NO animated:YES] 

然后我的观点保持不变(一切都回到我所期待的)

如果我在closures时不打电话给下面的行

 self.searchDisplayController.searchBar.translatesAutoresizingMaskIntoConstraints = NO 

然后视图拧紧。

我相信的原因是NSAutoresizingMaskLayoutConstraint声明它们是自我的,因为它们是约束列表中的最后一个,所以布局引擎制动实际约束以满足不想要的NSAutoresizingMaskLayout约束约束。