显示 searchResultsController 时出现 UISearchBar AutoLayout 错误
UISearchBar AutoLayout Error On Presentation of searchResultsController
我正在尝试让 UISearchBar
+ UISearchController
在 Obj-C 中工作,并遵循 Apple 的示例代码 here。我不想像示例中那样在 table 视图 header 中设置搜索栏,因此我设置了约束以将其固定在主视图控制器的顶部。这适用于定位,但是当我点击搜索栏并尝试以模式方式呈现结果 table 视图控制器(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)]];
}
解决方案:(回应达门)
按照 Zoo 的建议,我在 Interface Builder 中添加了一个容器视图,限制在父视图的顶部和两侧,高度为 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;
}
我正在尝试让 UISearchBar
+ UISearchController
在 Obj-C 中工作,并遵循 Apple 的示例代码 here。我不想像示例中那样在 table 视图 header 中设置搜索栏,因此我设置了约束以将其固定在主视图控制器的顶部。这适用于定位,但是当我点击搜索栏并尝试以模式方式呈现结果 table 视图控制器(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)]];
}
解决方案:(回应达门)
按照 Zoo 的建议,我在 Interface Builder 中添加了一个容器视图,限制在父视图的顶部和两侧,高度为 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;
}