如果我在displaysSearchBarInNavigationBar = YES
中设置viewDidLoad
,则当视图显示时,搜索栏将位于导航栏中。但是当我触摸栏按钮项目时,我想在导航栏顶部显示搜索栏。这就像下面的图片
正常导航栏:
单击右侧栏按钮项后,在导航栏的顶部上单击搜索栏
答案 0 :(得分:41)
我已经修改了Mark的答案,以便在IOS 8和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()
}
}
答案 1 :(得分:40)
我认为基本的想法是动画现有导航栏项目的淡出(leftBarButtonItem(s),titleView,rightBarButtonItem(s)),然后是搜索栏后的动画淡入。添加为navigationItem的标题视图。要还原,请为搜索栏的淡出设置设置动画,然后替换navigationBar的先前项目。
下面粗略示例中的searchBar是独立的,但也可能来自其他地方,例如iOS8的新UISearchController。它还假定视图控制器嵌入在UINavigationController中。
此示例以编程方式构建UI,但您应该能够将此方法与Storyboard构建的UI结合使用。
当用户点击“取消”按钮时发生的动画有点粗糙,但希望可能指向更顺畅的解决方案。
@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
答案 2 :(得分:6)
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)")
}
}
答案 3 :(得分:5)
我刚刚重构了Nick的答案,使其在Swift 4中成为POP方式。
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
})
}
}
然后您可以像这样使用它
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)
}
}