显示 searchResultsController 时出现 UISearchBar AutoLayout 错误

Posted

技术标签:

【中文标题】显示 searchResultsController 时出现 UISearchBar AutoLayout 错误【英文标题】:UISearchBar AutoLayout Error On Presentation of searchResultsController 【发布时间】:2015-02-01 05:52:39 【问题描述】:

我正在尝试让 UISearchBar + UISearchController 在 Obj-C 中工作,并遵循 Apple 的示例代码 here。我不想在表格视图标题中设置搜索栏,就像他们在示例中所做的那样,所以我设置约束以将其粘贴到主视图控制器的顶部。这适用于定位,但是当我点击搜索栏并尝试以模态方式显示结果表视图控制器 (searchResultsTVC) 时,它会在约束上引发错误:

2015-02-01 00:36:47.539 Search-FeatureTest[15521:3760972] The view hierarchy is not prepared for the constraint: <NSLayoutConstraint:0x7fc911c77f90 UISearchBar:0x7fc911c6b880.left == UIView:0x7fc911c69b70.left>
When added to a view, the constraint's items must be descendants of that view (or the view itself). This will crash if the constraint needs to be resolved before the view hierarchy is assembled. Break on -[UIView _viewHierarchyUnpreparedForConstraint:] to debug.
2015-02-01 00:36:47.539 Search-FeatureTest[15521:3760972] *** Assertion failure in -[UIView _layoutEngine_didAddLayoutConstraint:roundingAdjustment:mutuallyExclusiveConstraints:], /SourceCache/UIKit_Sim/UIKit-3318.16.14/NSLayoutConstraint_UIKitAdditions.m:560
2015-02-01 00:36:47.541 Search-FeatureTest[15521:3760972] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Impossible to set up layout with view hierarchy unprepared for constraint.'
*** First throw call stack:
(
    0   CoreFoundation                      0x00000001047aef35 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x0000000104447bb7 objc_exception_throw + 45
    2   CoreFoundation                      0x00000001047aed9a +[NSException raise:format:arguments:] + 106
    3   Foundation                          0x00000001040645df -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 195
    4   UIKit                               0x0000000105215cf2 __120-[UIView(UIConstraintBasedLayout) _layoutEngine_didAddLayoutConstraint:roundingAdjustment:mutuallyExclusiveConstraints:]_block_invoke_2 + 177
    5   UIKit                               0x0000000105215be7 -[UIView(UIConstraintBasedLayout) _layoutEngine_didAddLayoutConstraint:roundingAdjustment:mutuallyExclusiveConstraints:] + 377
    6   UIKit                               0x0000000105215ea4 -[UIView(UIConstraintBasedLayout) _tryToAddConstraintWithoutUpdatingConstraintsArray:roundingAdjustment:mutuallyExclusiveConstraints:] + 30
    7   UIKit                               0x0000000105215fcc -[UIView(UIConstraintBasedLayout) _tryToAddConstraint:roundingAdjustment:mutuallyExclusiveConstraints:] + 243
    8   UIKit                               0x000000010521630b __50-[UIView(UIConstraintBasedLayout) addConstraints:]_block_invoke + 188
    9   Foundation                          0x0000000103fedd6e -[NSISEngine withBehaviors:performModifications:] + 155
    10  UIKit                               0x0000000105216240 -[UIView(UIConstraintBasedLayout) addConstraints:] + 263
    11  UIKit                               0x000000010520f112 -[_UISearchPresentationController presentationTransitionWillBegin] + 759
    12  UIKit                               0x0000000104ca00a7 __71-[UIPresentationController _initViewHierarchyForPresentationSuperview:]_block_invoke + 1398
    13  UIKit                               0x0000000104c9eb50 __56-[UIPresentationController runTransitionForCurrentState]_block_invoke + 175
    14  UIKit                               0x0000000104bbe331 _applyBlockToCFArrayCopiedToStack + 314
    15  UIKit                               0x0000000104bbe1ab _afterCACommitHandler + 516
    16  CoreFoundation                      0x00000001046e3dc7 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
    17  CoreFoundation                      0x00000001046e3d20 __CFRunLoopDoObservers + 368
    18  CoreFoundation                      0x00000001046d9b53 __CFRunLoopRun + 1123
    19  CoreFoundation                      0x00000001046d9486 CFRunLoopRunSpecific + 470
    20  GraphicsServices                    0x0000000107d7d9f0 GSEventRunModal + 161
    21  UIKit                               0x0000000104b9b420 UIApplicationMain + 1282
    22  Search-FeatureTest                  0x0000000103f19043 main + 115
    23  libdyld.dylib                       0x0000000106d3e145 start + 1
 )
libc++abi.dylib: terminating with uncaught exception of type NSException

这是我初始化搜索控制器和搜索栏约束的代码:

- (void)viewDidLoad 
    [super viewDidLoad];

    self.searchResultsTVC = [[SearchResultsTVC alloc]init];
    self.allObjects = [NSMutableArray arrayWithArray:@[@"A", @"AA", @"ABBA", @"B", @"BOB", @"C", @"D", @"E", @"F", @"G", @"H"]];

    self.searchController = [[UISearchController alloc]initWithSearchResultsController:self.searchResultsTVC];
    [self.searchController setSearchResultsUpdater:self];
    [self.searchController setDelegate:self];

    [self.searchController.searchBar setDelegate:self];
    [self.view addSubview:self.searchController.searchBar];

    //constraints for searchBar
    [self.searchController.searchBar setTranslatesAutoresizingMaskIntoConstraints:NO];
    UISearchBar *searchBar = self.searchController.searchBar;
    id topLayoutGuide = self.topLayoutGuide;

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[searchBar]|" options:NSLayoutFormatDirectionLeftToRight metrics:nil views:NSDictionaryOfVariableBindings(searchBar)]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[topLayoutGuide][searchBar]" options:NSLayoutFormatDirectionLeftToRight metrics:nil views:NSDictionaryOfVariableBindings(topLayoutGuide, searchBar)]];


【问题讨论】:

我还没有找到解决方案。目前,我将尝试通过将其放入没有行的 tableView 中来破解它,将搜索栏作为页眉,将视图的其余部分作为页脚。 我通过将 UISearchBar 放在 UIView 中,然后在 UIView 上添加约束解决了这个问题。 那行得通——不敢相信我没想到。谢谢! @MattCooper 做了同样的事情——对我没用。你能粘贴工作代码吗? 如果你将 UISearchBar 放在 UIView 中,你是否会从栏添加约束到视图以确保栏大小正确,例如,屏幕旋转?这不会导致同样的错误吗? 【参考方案1】:

解决方案:(回应达门)

按照 Zoo 的建议,我在界面生成器中添加了一个容器视图,限制在超级视图的顶部和侧面,高度为 44。

然后我将搜索栏放在视图中,如下所示:

- (void)viewDidLoad 
    [super viewDidLoad];

    self.searchController = [[UISearchController alloc]initWithSearchResultsController:<Your SearchResultsController>];
    [self.searchController setSearchResultsUpdater:self];
    [self.searchController setDelegate:self];

    [self.searchController.searchBar setDelegate:self];

    [self.searchBarContainer addSubview:self.searchController.searchBar];

    self.definesPresentationContext = YES;

【讨论】:

以上是关于显示 searchResultsController 时出现 UISearchBar AutoLayout 错误的主要内容,如果未能解决你的问题,请参考以下文章

Windows 逆向OD 调试器工具 ( 显示模块窗口 | 显示记录窗口 | 显示内存窗口 | 显示线程 | 显示句柄 | 显示 CPU | 多窗口界面 )

电脑显示只显示时间不显示日期怎么办?怎么解决?

css 如何根据显示器屏幕大小自动调整显示区域

CRT显示器是怎么实现彩色显示的?

笔记本双屏显示怎样设置

电脑显示器为啥有亮光却没有文字