ios - Cómo animar agregar UISearchBar en la parte superior de UINavigationBar
(3)
Creo que la idea básica sería animar un fundido de salida de los elementos de su barra de navegación existente (leftBarButtonItem (s), titleView, rightBarButtonItem (s)), seguido de un fade-in animado de su barra de búsqueda después de que se agrega como su Vista del título de navigationItem Para revertir, anima un fundido de salida de la barra de búsqueda, seguido de un reemplazo de los elementos anteriores de su barra de navegación.
La barra de búsqueda en el siguiente ejemplo es independiente, pero también podría venir de otro lugar, como el nuevo UISearchController de iOS8. También asume que el controlador de vista está incrustado en un UINavigationController.
Este ejemplo crea la interfaz de usuario de forma programática, pero debería poder incorporar este enfoque con una interfaz de usuario construida con Storyboard.
La animación que se produce cuando el usuario toca el botón "Cancelar" es un poco difícil, pero con suerte podría indicar el camino a una solución más suave.
@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
Si configuro viewDidLoad
displaysSearchBarInNavigationBar = YES
en viewDidLoad
, la barra de búsqueda estará en la barra de navegación cuando aparezca la vista. Pero quiero mostrar la barra de búsqueda en la parte superior de la barra de navegación cuando toco el elemento del botón de barra. Es como la imagen a continuación
barra de navegación normal :
barra de búsqueda en la parte superior de la barra de navegación después de hacer clic en el elemento del botón de la barra derecha
Modifiqué un poco la respuesta de Mark para que funcione en iOS 8 y en poco tiempo.
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()
}
}
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)")
}
}