UISearchBar忽略了程序性约束

时间:2016-09-20 23:14:04

标签: ios objective-c nslayoutconstraint uisearchcontroller ios-autolayout

我正在尝试构建一个利用UISearchController来显示结果的ViewController子类。该视图有一个输入字段,我希望将其设置为屏幕顶部的动画,以便用户有最大的空间来查看结果。

我使用UIView构建了一个概念验证,该UIView包含一个Search Bar插入组件,并在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];
    }];
}

然后我尝试切换到以编程方式创建的UISearchControllerUISearchBar。以下代码设置了我认为代码中的等效关系,而不是在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而不是显式添加它,但行为完全相同。更新代码以匹配。

1 个答案:

答案 0 :(得分:1)

将UISearchController的searchBar添加到UITableView标题视图时,我遇到了类似的问题。

在用户选择了searchBar后,当持有UITableView的containerView的约束动画时,它不会跟随containerView。

在我的情况下,似乎在调用委托 didPresentSearchController:(UISearchController *)searchController 之后,searchBar具有UISearchBarContainerView的超级视图而不是UITableView标头视图。

在动画帮助我之前,将其重新添加回原始标题视图。

-(void)didPresentSearchController:(UISearchController *)searchController {

    NSLog(@"did present search controller");

    self.tableView.tableHeaderView = self.searchController.searchBar;

    ...animation...

}