I'm trying to build a ViewController subclass that leverages a UISearchController to display results. The view has an input field that I want to animate up to the top of the screen so the user has a maximum amount of room to view the results.
I built out a proof of concept using a UIView that wraps a Search Bar drop-in component and set their top, leading, trailing, and bottom constraints equal in a Storyboard. The following code is responsible for animating the different movements:
- (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];
}];
}
I then tried switching over to a programatically created UISearchController
and UISearchBar
. The following code sets up what I thought was the equivalent relationship in code instead of in the 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;
However, when done this way the UISearchBar
object does not obey the constraints. When the container is animated up, the search bar flies off the page. Why is this happening?
Minor Update: I noticed in the documentation for NSLayoutConstraint
to set its active property to YES
instead of explicitly adding it, but the behavior is exactly the same. Updating code to match.