【问题标题】:How to animate add UISearchBar on top of UINavigationBar如何在 UINavigationBar 上添加 UISearchBar 动画
【发布时间】:2014-07-06 07:22:38
【问题描述】:

如果我在viewDidLoad 中设置displaysSearchBarInNavigationBar = YES,当视图显示时,搜索栏将在导航栏中。但是当我触摸栏按钮项时,我想在导航栏顶部显示搜索栏。如下图所示

普通导航栏:

点击右栏按钮项目后导航栏顶部上的搜索栏

【问题讨论】:

  • 我认为这篇文章已经回答了你的问题stackoverflow.com/questions/5095477/…
  • @F1ank3r 但是它没有提到当有人点击一个按钮时如何在导航栏顶部添加搜索栏,然后点击取消隐藏搜索栏。我知道如何在导航栏上添加搜索栏。
  • @yongho,你找到解决问题的方法了吗?如果是这样,请在此处发布方法。我正在寻找相同问题的解决方案。
  • @yongho 你也是用搜索功能实现的吗?我很高兴看到一些代码。答案对我不起作用。

标签: ios uinavigationbar uisearchbar


【解决方案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 = 0navigationItem.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)")
    
        }    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-13
      • 1970-01-01
      相关资源
      最近更新 更多