Search code examples
iosswiftuinavigationbaruibarbuttonitemuinavigationitem

UIBarButtonItems wont show in navigationBar


I've created a navigationBar in my view which is suppose to hold 2 buttons left and right. The problem is whatever i do it wont show the buttons/views. How am i suppose to do this? here is my code so far.

enter image description here

override func viewDidLoad() {
    super.viewDidLoad()



    self.navigationController?.navigationBar.titleTextAttributes = [ NSFontAttributeName: UIFont(name: "Aerovias Brasil NF", size: 30)!,  NSForegroundColorAttributeName: UIColor.whiteColor()]

    navTitleView = UIView(frame: CGRectMake(0, 0, 100, 44))
    titleLabel.text = "SHOPOP"
    navTitleView?.addSubview(titleLabel)
    self.navigationItem.titleView?.addSubview(navTitleView!)

    navigationHeight = UIApplication.sharedApplication().statusBarFrame.height+self.navigationController!.navigationBar.bounds.height

    searchBar = UISearchBar(frame: CGRectZero)
    searchBarWrapper = UINavigationBar(frame: CGRectMake(0, 100, self.navigationController!.navigationBar.bounds.size.width, self.navigationHeight!))
    var buttonSearchBar:UIBarButtonItem = UIBarButtonItem(customView: searchBar!)
    var cancelButton:UIBarButtonItem = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.Plain, target: nil, action: nil)
    searchBarWrapper?.topItem?.leftBarButtonItem = buttonSearchBar
    searchBarWrapper?.topItem?.rightBarButtonItem = cancelButton

    self.navigationController?.view.addSubview(searchBarWrapper!)


}


@IBAction func showSearchBar(sender: UIBarButtonItem) {


    searchBar?.becomeFirstResponder()
    UIView.animateWithDuration(0.25,  animations: {
        // Optional chaining may return nil
        self.searchBarWrapper!.center = CGPointMake(self.navigationController!.view.center.x, self.navigationHeight!/2)


        // return
        }, completion: {
            finished in
            println("Basket doors opened!")
    })

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

@IBAction func hideSearchBar(sender: UIBarButtonItem) {

    UIView.animateWithDuration(0.25,  animations: {
        // Optional chaining may return nil
        self.searchBarWrapper!.center = CGPointMake(self.navigationController!.view.center.x, -self.navigationHeight!/2)

        self.searchBar?.resignFirstResponder()

        // return
        }, completion: {
            finished in
            println("Basket doors opened!")
    })

Solution

  • Based on the changes to your question you should look into the UISearchController class. A cursory glance at the documentation leads me to believe that after you configure it properly you can push it onto the view controller stack and it will behave like you want.


    Old answer:

    While I'm not sure about wrapping a UISearchBar inside of a UIBarButtonItem I can say with certainty that this is the wrong way to go about adding a UINavigationBar to a UINavigationController:

    self.navigationController?.view.addSubview(searchBarWrapper!)
    

    The right way to go about providing items for the navigation bar is to override UIViewController's navigationItem property and return a customized UINavigationItem instance. This way when you push and pop view controllers off of the UINavigationController's stack the navigation bar will be updated automatically.

    This is an example from a UIViewController subclass in one of my projects.

    private var customNavigationItem = UINavigationItem(title:nil);
    
    override var navigationItem:UINavigationItem
    {
        get
        {
            customNavigationItem.title = self.title;
            customNavigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem:.Cancel,
                target:self, action:"dismissForm:");
            customNavigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem:.Save,
                target:self, action:"saveForm:");
    
            return customNavigationItem;
        }
    }
    

    Doing this will ensure that all of the "free" functionality that UINavigationController provides works as intended. Messing with UINavigationController's view is generally a bad idea.