UISearchBar 忽略编程约束
UISearchBar ignores programmatic constraints
我正在尝试构建一个 ViewController 子类,它利用 UISearchController 来显示结果。该视图有一个输入字段,我想将其动画化到屏幕顶部,以便用户有最大的空间来查看结果。
我使用 UIView 构建了一个概念证明,该 UIView 包装了一个搜索栏下拉组件,并在 Storyboard 中将它们的顶部、前导、尾随和底部约束设置为相等。以下代码负责为不同的动作设置动画:
- (void)keyboardWillAppear:(NSNotification*)notification {
self.labelToSearchBarSpaceConstraint.active = NO;
self.searchBarAtTopConstraint.active = YES;
self.searchBarLeadingSpaceConstraint.constant = 0;
self.searchBarTrailingSpaceConstraint.constant = 0;
[UIView animateWithDuration:[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue] animations:^{
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];
}
- (void)keyboardWillDisappear:(NSNotification*)notification {
self.searchBarAtTopConstraint.active = NO;
self.labelToSearchBarSpaceConstraint.active = YES;
self.searchBarLeadingSpaceConstraint.constant = 20;
self.searchBarTrailingSpaceConstraint.constant = 20;
[UIView animateWithDuration: [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue] animations:^{
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];
}
然后我尝试切换到以编程方式创建的 UISearchController
和 UISearchBar
。下面的代码建立了我认为是代码而不是 Storyboard 中的等价关系:
self.definesPresentationContext = YES;
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
UISearchBar* searchBar = self.searchController.searchBar;
searchBar.translatesAutoresizingMaskIntoConstraints = NO;
[self.searchBarView addSubview:searchBar];
[NSLayoutConstraint constraintWithItem:searchBar attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.searchBarView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0].active = YES;
[NSLayoutConstraint constraintWithItem:searchBar attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.searchBarView attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0.0].active = YES;
[NSLayoutConstraint constraintWithItem:searchBar attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.searchBarView attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0.0].active = YES;
[NSLayoutConstraint constraintWithItem:searchBar attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.searchBarView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0].active = YES;
然而,当以这种方式完成时,UISearchBar
对象不遵守约束。当容器向上动画时,搜索栏会飞出页面。为什么会这样?
次要更新:我在 NSLayoutConstraint
的文档中注意到将其活动 属性 设置为 YES
而不是显式添加它,但行为完全相同。更新代码以匹配。
我在将 UISearchController 的搜索栏添加到 UITableView header 视图时遇到了类似的问题。
在用户选择 searchBar 后,当包含 UITableView 的 containerView 的动画约束时,它不会跟随 containerView。
在我的例子中,在委托 didPresentSearchController:(UISearchController *)searchController 被调用后,searchBar 有一个 UISearchBarContainerView 的超级视图而不是 UITableView header 看法。
Re-adding 它回到了动画帮助我之前的原始 header 视图。
-(void)didPresentSearchController:(UISearchController *)searchController {
NSLog(@"did present search controller");
self.tableView.tableHeaderView = self.searchController.searchBar;
...animation...
}
我正在尝试构建一个 ViewController 子类,它利用 UISearchController 来显示结果。该视图有一个输入字段,我想将其动画化到屏幕顶部,以便用户有最大的空间来查看结果。
我使用 UIView 构建了一个概念证明,该 UIView 包装了一个搜索栏下拉组件,并在 Storyboard 中将它们的顶部、前导、尾随和底部约束设置为相等。以下代码负责为不同的动作设置动画:
- (void)keyboardWillAppear:(NSNotification*)notification {
self.labelToSearchBarSpaceConstraint.active = NO;
self.searchBarAtTopConstraint.active = YES;
self.searchBarLeadingSpaceConstraint.constant = 0;
self.searchBarTrailingSpaceConstraint.constant = 0;
[UIView animateWithDuration:[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue] animations:^{
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];
}
- (void)keyboardWillDisappear:(NSNotification*)notification {
self.searchBarAtTopConstraint.active = NO;
self.labelToSearchBarSpaceConstraint.active = YES;
self.searchBarLeadingSpaceConstraint.constant = 20;
self.searchBarTrailingSpaceConstraint.constant = 20;
[UIView animateWithDuration: [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue] animations:^{
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];
}
然后我尝试切换到以编程方式创建的 UISearchController
和 UISearchBar
。下面的代码建立了我认为是代码而不是 Storyboard 中的等价关系:
self.definesPresentationContext = YES;
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
UISearchBar* searchBar = self.searchController.searchBar;
searchBar.translatesAutoresizingMaskIntoConstraints = NO;
[self.searchBarView addSubview:searchBar];
[NSLayoutConstraint constraintWithItem:searchBar attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.searchBarView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0].active = YES;
[NSLayoutConstraint constraintWithItem:searchBar attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.searchBarView attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0.0].active = YES;
[NSLayoutConstraint constraintWithItem:searchBar attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.searchBarView attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0.0].active = YES;
[NSLayoutConstraint constraintWithItem:searchBar attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.searchBarView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0].active = YES;
然而,当以这种方式完成时,UISearchBar
对象不遵守约束。当容器向上动画时,搜索栏会飞出页面。为什么会这样?
次要更新:我在 NSLayoutConstraint
的文档中注意到将其活动 属性 设置为 YES
而不是显式添加它,但行为完全相同。更新代码以匹配。
我在将 UISearchController 的搜索栏添加到 UITableView header 视图时遇到了类似的问题。
在用户选择 searchBar 后,当包含 UITableView 的 containerView 的动画约束时,它不会跟随 containerView。
在我的例子中,在委托 didPresentSearchController:(UISearchController *)searchController 被调用后,searchBar 有一个 UISearchBarContainerView 的超级视图而不是 UITableView header 看法。
Re-adding 它回到了动画帮助我之前的原始 header 视图。
-(void)didPresentSearchController:(UISearchController *)searchController {
NSLog(@"did present search controller");
self.tableView.tableHeaderView = self.searchController.searchBar;
...animation...
}