如何在 UINavigationBar 上添加 UISearchBar 动画
Posted
技术标签:
【中文标题】如何在 UINavigationBar 上添加 UISearchBar 动画【英文标题】:How to animate add UISearchBar on top of UINavigationBar 【发布时间】:2014-07-06 07:22:38 【问题描述】:如果我在viewDidLoad
中设置displaysSearchBarInNavigationBar = YES
,当视图显示时,搜索栏将在导航栏中。但是当我触摸栏按钮项时,我想在导航栏顶部显示搜索栏。如下图所示
普通导航栏:
点击右栏按钮项目后导航栏顶部上的搜索栏
【问题讨论】:
我认为这篇文章已经回答了你的问题***.com/questions/5095477/… @F1ank3r 但是它没有提到当有人点击一个按钮时如何在导航栏顶部添加搜索栏,然后点击取消隐藏搜索栏。我知道如何在导航栏上添加搜索栏。 @yongho,你找到解决问题的方法了吗?如果是这样,请在此处发布方法。我正在寻找相同问题的解决方案。 @yongho 你也是用搜索功能实现的吗?我很高兴看到一些代码。答案对我不起作用。 【参考方案1】:我稍微修改了 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()
【讨论】:
更改行的顺序:searchBar.alpha = 0
和 navigationItem.titleView = searchBar
使它对我有用。
我用过这个,但是如果右侧导航栏中有两个按钮,标题视图会稍微推到左侧
我还添加了searchBar.showsCancelButton = true
以显示“取消”按钮。
不错!感谢您添加 Swift 示例。【参考方案2】:
我认为基本的想法是动画淡出现有导航栏的项目(leftBarButtonItem(s)、titleView、rightBarButtonItem(s)),然后是搜索栏的动画淡入。添加为您的 navigationItem 的标题视图。要恢复,请为搜索栏的淡出设置动画,然后替换您的导航栏先前的项目。
下面粗略示例中的 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
【讨论】:
我正在尝试使用您的方法,但我收到此错误 Assigning to 'UIButton __strong' from in compatible type 'float' 在这一行** _searchButton.alpha = 0.0f;* 我必须查看更多您的代码才能提供帮助。 .alpha 通道是 UIButton 的有效属性。您的代码是否读取“_searchButton.alpha = 0.0f;”或“_searchButton = 0.0f;” (没有 alpha 属性)? 我没有尝试过,但我已经删除了那条线路并且它可以工作。 Alpha 仅用于设置透明度【参考方案3】:我刚刚重构了 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)
【讨论】:
【参考方案4】: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)")
【讨论】:
以上是关于如何在 UINavigationBar 上添加 UISearchBar 动画的主要内容,如果未能解决你的问题,请参考以下文章
如何在 iOS 11 中引入的 UINavigationBar 的大标题视图上添加自定义视图
如何以编程方式将 UIBarButtonItem 添加到拖到视图上的 UINavigationBar
如何将全局 barButtonItems 添加到自定义 UINavigationBar?
按下 UINavigationController 后如何将编辑按钮添加到 UINavigationBar