webentwicklung-frage-antwort-db.com.de

So animieren Sie das Hinzufügen von UISearchBar über UINavigationBar

Wenn ich das displaysSearchBarInNavigationBar = YES in viewDidLoad befindet sich die Suchleiste in der Navigationsleiste, wenn die Ansicht angezeigt wird. Ich möchte jedoch die Suchleiste oben in der Navigationsleiste anzeigen, wenn ich das Schaltflächenelement der Leiste berühre. Es ist wie das Bild unten

normal Navigationsleiste: enter image description here

suchleiste auf oben der Navigationsleiste nach dem Klicken auf die Schaltfläche in der rechten Leiste enter image description here

42
yong ho

Ich habe Marks Antwort ein wenig modifiziert, damit sie in IOS 8 und in Swift funktioniert.

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()
  }
}
41
Nick Wargnier

Ich denke, die Grundidee wäre, ein Ausblenden der Elemente Ihrer vorhandenen Navigationsleiste (leftBarButtonItem (s), titleView, rightBarButtonItem (s)) zu animieren, gefolgt von einem animierten Einblenden Ihrer Suchleiste, nachdem sie als Ihre hinzugefügt wurde Titelansicht von navigationItem. Zum Zurücksetzen animieren Sie ein Ausblenden der Suchleiste, gefolgt von einem Ersetzen der vorherigen Elemente Ihrer navigationBar.

Die searchBar im Beispiel unten ist eigenständig, kann jedoch auch von einer anderen Stelle stammen, z. B. dem neuen UISearchController von iOS8. Es wird außerdem davon ausgegangen, dass der Ansichtscontroller in einen UINavigationController eingebettet ist.

In diesem Beispiel wird die Benutzeroberfläche programmgesteuert erstellt. Sie sollten jedoch in der Lage sein, diesen Ansatz in eine vom Storyboard erstellte Benutzeroberfläche zu integrieren.

Die Animation, die auftritt, wenn der Benutzer auf die Schaltfläche "Abbrechen" tippt, ist etwas rau, weist jedoch hoffentlich den Weg zu einer reibungsloseren Lösung.

@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
40
Mark Semsel
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.

enter image description hereenter image description here

//  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)")

    }    
}
6
A.G

Ich habe gerade Nicks Antwort überarbeitet, um es 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

    })
 }
}

Dann können Sie es so verwenden

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)
  }
}
5
osama