Si je règle le displaysSearchBarInNavigationBar = YES
dans viewDidLoad
, la barre de recherche sera dans la barre de navigation lorsque la vue apparaîtra. Mais je veux afficher la barre de recherche en haut de la barre de navigation lorsque je touche un élément de bouton de barre. C'est comme l'image ci-dessous
normal barre de navigation:
barre de recherche sur en haut de la barre de navigation après avoir cliqué sur l'élément du bouton de la barre de droite
J'ai un peu modifié la réponse de Mark pour le faire fonctionner dans IOS 8 et dans 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()
}
}
Je pense que l'idée de base serait d'animer un fondu sortant des éléments de votre barre de navigation existante (leftBarButtonItem (s), titleView, rightBarButtonItem (s)), suivi d'un fondu animé de votre barre de recherche après son ajout en tant que votre navigation Vue titre de l'objet. Pour revenir en arrière, animez un fondu sortant de la barre de recherche, suivi d'un remplacement des éléments précédents de votre barre de navigation.
La barre de recherche dans l'exemple approximatif ci-dessous est autonome, mais elle pourrait également venir d'ailleurs, comme le nouveau UISearchController d'iOS8. Il suppose également que le contrôleur de vue est intégré dans un UINavigationController.
Cet exemple crée l'interface utilisateur par programme, mais vous devriez être en mesure d'incorporer cette approche à une interface utilisateur créée par Storyboard.
L'animation qui se produit lorsque l'utilisateur appuie sur le bouton "Annuler" est un peu approximative, mais nous espérons qu'elle pourrait indiquer la voie vers une solution plus fluide.
@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
Following Nick's answer, I made a similar one on Xcode 7.1 -Swift 2.0.
Note:
To the Navigation Bar, I added
(a) UIBarButtons( Drag& Drop) - menuButton & searchButton
(b) UIBarButtons (programatically) - leftSearchBarButtonItem & rightSearchBarButtonItem.
The common methods are :
(a) showSearchBar(), hideSearchBar()
(b) revealToggle: - It is connected to SWRevealController for Slider Menu.
// DashBoardViewController.Swift
import UIKit
class DashBoardViewController: UIViewController,UISearchBarDelegate,SWRevealViewControllerDelegate {
//MARK:- STORYBOARD REFERENCE
@IBOutlet weak var menuButton: UIBarButtonItem!
@IBOutlet weak var searchButtton: UIBarButtonItem!
//Making secondary Searchbar
var searchBar = UISearchBar()
var leftSearchBarButtonItem: UIBarButtonItem?
var rightSearchBarButtonItem: UIBarButtonItem?
var logoImageView : UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
self.activateInitialUISetUp()
// self.revealViewController().delegate = self
makeTopNavigationSearchbar()
}
override func viewWillAppear(animated: Bool) {
makeTopNavigationSearchbar()
activateInitialUISetUp()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
//MARK:- SEARCHBAR METHODS
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
hideSearchBar()
searchBar.resignFirstResponder()
}
func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
}
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
hideSearchBar()
}
//Search Bar Appear & Disappear
func showSearchBar() {
searchBar.hidden = false
searchBar.alpha = 0
navigationItem.titleView = searchBar
navigationItem.setLeftBarButtonItem(nil, animated: true)
navigationItem.setRightBarButtonItem(nil, animated: true)
UIView.animateWithDuration(0.5, animations: {
self.searchBar.alpha = 1
}, completion: { finished in
self.searchBar.becomeFirstResponder()
})
}
func hideSearchBar() {
hideSearchBarAndMakeUIChanges()
logoImageView.alpha = 0
UIView.animateWithDuration(0.3, animations: {
self.logoImageView.alpha = 1
}, completion: { finished in
})
}
//Making secondary Searchbar
func makeTopNavigationSearchbar()
{
let logoImage = UIImage(named: "password")!
logoImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: logoImage.size.width, height: logoImage.size.height))
logoImageView.image = logoImage
searchButtton.customView?.addSubview(logoImageView)
searchBar.delegate = self
searchBar.searchBarStyle = UISearchBarStyle.Minimal
leftSearchBarButtonItem = navigationItem.leftBarButtonItem
rightSearchBarButtonItem = navigationItem.rightBarButtonItem
leftSearchBarButtonItem?.tintColor = UIColor.whiteColor()
rightSearchBarButtonItem?.tintColor = UIColor.whiteColor()
}
//Adding secondary uibar butttons to navigation bar
func hideSearchBarAndMakeUIChanges ()
{
searchBar.hidden = true
//Adding secondary uibarbuttons to the nav bar and revoke its methods
navigationItem.setLeftBarButtonItem(leftSearchBarButtonItem, animated: true)
navigationItem.setRightBarButtonItem(rightSearchBarButtonItem, animated: true)
leftSearchBarButtonItem?.title = "Menu"
leftSearchBarButtonItem?.target = self.revealViewController()
leftSearchBarButtonItem?.action = "revealToggle:"
rightSearchBarButtonItem?.title = "Search"
rightSearchBarButtonItem?.target = self
rightSearchBarButtonItem?.action = "showSearchBar"
//Adding Title Label
var navigationTitlelabel = UILabel(frame: CGRectMake(0, 0, 200, 21))
navigationTitlelabel.center = CGPointMake(160, 284)
navigationTitlelabel.textAlignment = NSTextAlignment.Center
navigationTitlelabel.textColor = UIColor.whiteColor()
navigationTitlelabel.text = "WORK ORDER"
self.navigationController!.navigationBar.topItem!.titleView = navigationTitlelabel
}
//UI-Related Methods
func activateInitialUISetUp()
{
self.navigationController?.navigationBarHidden = false
self.navigationController?.navigationBar.barStyle = UIBarStyle.BlackOpaque
self.navigationController?.navigationBar.translucent = true
self.navigationController?.navigationBar.backgroundColor = UIColor.redColor()
//Nav Bar Searchbar
searchBar.delegate = self
searchBar.placeholder = "Start Your Search Here"
searchButtton.action = "showSearchBar"
searchButtton.target = self
//searchbar Text Color
var textFieldInsideSearchBar = searchBar.valueForKey("searchField") as? UITextField
textFieldInsideSearchBar?.textColor = UIColor.whiteColor()
//Nav Bar Title
self.title = "WORK ORDER"
if self.revealViewController() != nil {
menuButton.target = self.revealViewController()
menuButton.action = "revealToggle:"
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
self.revealViewController().rearViewRevealWidth = self.view.frame.width / 2
self.revealViewController().rearViewRevealOverdraw = 0.0
self.view.addGestureRecognizer(self.revealViewController().tapGestureRecognizer())
}
}
func revealController(revealController: SWRevealViewController!, didMoveToPosition position: FrontViewPosition) {
if(position.rawValue == 3)
{
}
else
{
}
print("position\(position)")
}
}
Je viens de refactoriser la réponse de Nick pour en faire la méthode POP dans Swift 4.
protocol SearchViewAnimateble : class{ }
extension SearchViewAnimateble where Self: UIViewController{
func showSearchBar(searchBar : UISearchBar) {
searchBar.alpha = 0
navigationItem.titleView = searchBar
navigationItem.setRightBarButton(nil, animated: true)
UIView.animate(withDuration: 0.5, animations: {
searchBar.alpha = 1
}, completion: { finished in
searchBar.becomeFirstResponder()
})
}
func hideSearchBar( searchBarButtonItem : UIBarButtonItem, titleView : UIView) {
navigationItem.setRightBarButton(searchBarButtonItem, animated: true)
titleView.alpha = 0
UIView.animate(withDuration: 0.3, animations: {
self.navigationItem.titleView = titleView
titleView.alpha = 1
}, completion: { finished in
})
}
}
Ensuite, vous pouvez l'utiliser comme ceci
class ViewController : UIViewController, UISearchBarDelegate, SearchViewAnimateble {
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 = .minimal
searchBar.showsCancelButton = true
searchBarButtonItem = navigationItem.rightBarButtonItem
}
@IBAction func searchButtonPressed(sender: AnyObject) {
showSearchBar(searchBar: searchBar)
}
//MARK: UISearchBarDelegate
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
hideSearchBar( searchBarButtonItem : searchBarButton!, titleView : logoImageView)
}
}