How to animate add UISearchBar on top of UINavigationBar

后端 未结 4 1105
傲寒
傲寒 2020-12-07 08:44

If I set the displaysSearchBarInNavigationBar = YES in viewDidLoad, the search bar will be in navigation bar when the view show up. But I want to s

相关标签:
4条回答
  • 2020-12-07 09:16

    I have just refactored Nick's answer to make it the POP way in 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
    
        })
     }
    }
    

    Then you can use it like this

    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)
      }
    }
    
    0 讨论(0)
  • 2020-12-07 09:18

    I think the basic idea would be to animate a fade-out of your existing navigation bar's items (leftBarButtonItem(s), titleView, rightBarButtonItem(s)), followed by an animated fade-in of your search bar after it is added as your navigationItem's title view. To revert, animate a fade-out of the search bar, followed by a replacement of your navigationBar's prior items.

    The searchBar in the rough example below is stand-alone, but it could also come from elsewhere, like iOS8's new UISearchController. It also assumes that the view controller is embedded in a UINavigationController.

    This example builds the UI programmatically, but you should be able to incorporate this approach with a Storyboard-built UI.

    The animation that occurs when the user taps the "Cancel" button is a little rough, but hopefully might point the way to a smoother solution.

    @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
    
    0 讨论(0)
  • 2020-12-07 09:20
    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)")
    
        }    
    }
    
    0 讨论(0)
  • 2020-12-07 09:37

    I've modified Mark's answer a little to get it to work in IOS 8 and in 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()
      }
    }
    
    0 讨论(0)
提交回复
热议问题