If I set the displaysSearchBarInNavigationBar = YES
in viewDidLoad
, the search bar will be in navigation bar when the view show up. But I want to show search bar on top of navigation bar when I touch bar button item. It's like image below
normal navigation bar:
search bar on top of navigation bar after right bar button item clicked
I've modified Mark's answer a little to get it to work in IOS 8 and in swift.
class ViewController : UIViewController, UISearchBarDelegate {
var searchBar = UISearchBar()
var searchBarButtonItem: UIBarButtonItem?
var logoImageView : UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Can replace logoImageView for titleLabel of navbar
let logoImage = UIImage(named: "logo-navbar")!
logoImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: logoImage.size.width, height: logoImage.size.height))
logoImageView.image = logoImage
navigationItem.titleView = logoImageView
searchBar.delegate = self
searchBar.searchBarStyle = UISearchBarStyle.Minimal
searchBarButtonItem = navigationItem.rightBarButtonItem
}
@IBAction func searchButtonPressed(sender: AnyObject) {
showSearchBar()
}
func showSearchBar() {
searchBar.alpha = 0
navigationItem.titleView = searchBar
navigationItem.setLeftBarButtonItem(nil, animated: true)
UIView.animateWithDuration(0.5, animations: {
self.searchBar.alpha = 1
}, completion: { finished in
self.searchBar.becomeFirstResponder()
})
}
func hideSearchBar() {
navigationItem.setLeftBarButtonItem(searchBarButtonItem, animated: true)
logoImageView.alpha = 0
UIView.animateWithDuration(0.3, animations: {
self.navigationItem.titleView = self.logoImageView
self.logoImageView.alpha = 1
}, completion: { finished in
})
}
//MARK: UISearchBarDelegate
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
hideSearchBar()
}
}
I think the basic idea would be to animate a fade-out of your existing navigation bar's items (leftBarButtonItem(s), titleView, rightBarButtonItem(s)), followed by an animated fade-in of your search bar after it is added as your navigationItem's title view. To revert, animate a fade-out of the search bar, followed by a replacement of your navigationBar's prior items.
The searchBar in the rough example below is stand-alone, but it could also come from elsewhere, like iOS8's new UISearchController. It also assumes that the view controller is embedded in a UINavigationController.
This example builds the UI programmatically, but you should be able to incorporate this approach with a Storyboard-built UI.
The animation that occurs when the user taps the "Cancel" button is a little rough, but hopefully might point the way to a smoother solution.
@interface ViewController() <UISearchBarDelegate>
@property (nonatomic, strong) UIButton *searchButton;
@property (nonatomic, strong) UIBarButtonItem *searchItem;
@property (nonatomic, strong) UISearchBar *searchBar;
@end
- (void)viewDidLoad {
[super viewDidLoad];
// create the magnifying glass button
self.searchButton = [[UIButton alloc] init];
// add button images, etc.
[_searchButton addTarget:self action:@selector(searchButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
self.searchItem = [[UIBarButtonItem alloc] initWithCustomView:_searchButton];
self.navigationItem.rightBarButtonItem = _searchItem;
self.searchBar = [[UISearchBar alloc] init];
_searchBar.showsCancelButton = YES;
_searchBar.delegate = self;
}
- (void)searchButtonTapped:(id)sender {
[UIView animateWithDuration:0.5 animations:^{
_searchButton.alpha = 0.0f;
} completion:^(BOOL finished) {
// remove the search button
self.navigationItem.rightBarButtonItem = nil;
// add the search bar (which will start out hidden).
self.navigationItem.titleView = _searchBar;
_searchBar.alpha = 0.0;
[UIView animateWithDuration:0.5
animations:^{
_searchBar.alpha = 1.0;
} completion:^(BOOL finished) {
[_searchBar becomeFirstResponder];
}];
}];
}
#pragma mark UISearchBarDelegate methods
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
[UIView animateWithDuration:0.5f animations:^{
_searchBar.alpha = 0.0;
} completion:^(BOOL finished) {
self.navigationItem.titleView = nil;
self.navigationItem.rightBarButtonItem = _searchItem;
_searchButton.alpha = 0.0; // set this *after* adding it back
[UIView animateWithDuration:0.5f animations:^ {
_searchButton.alpha = 1.0;
}];
}];
}// called when cancel button pressed
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With