senty
senty

Reputation: 12847

Using Back on Navigation Bar bugs UIBarButtonItem

I have a NavigationBar at the top of a TableView. It looks nice opening/closing the search.

enter image description here

enter image description here


However, if I click on a button in a cell and get directed to another page (with segue); and then use Back button to unwind, it seems like bugged.

(enter image description here)

So it looks like it is pressed and opened but it shouldn't have. It should be looked like the top picture instead (just UIBarButtonItem - search button)

enter image description here


I couldn't figure out the issue creating this problem.

Please note that < Back is created automatically and I didn't write any code to create it. Is there something I am doing wrong?


Update: Added some snippets...

First, created a different class for handling the search

class SearchBarViewController: UIViewController, UISearchBarDelegate {

  var searchBar : UISearchBar?
  var searchBarWrapper : UIView?
  var searchBarButtonItem : UIBarButtonItem?

  func constructSearchBar()
  {
     searchBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Search, target: self, action: "showSearchBar")
     self.navigationItem.rightBarButtonItem = searchBarButtonItem
  }

  func showSearchBar() {
          // styling & configuration
   }

  func searchBarCancelButtonClicked(searchBar: UISearchBar) {

     UIView.animateWithDuration(0.2, animations: {
         self.searchBar?.resignFirstResponder()
         self.searchBarWrapper?.alpha = 0
         }, completion: { (success) -> Void in
             self.searchBar = nil
             self.searchBarWrapper = nil
             self.navigationItem.rightBarButtonItem = self.searchBarButtonItem
        })
    }
   }

And my ViewController:

 class ViewController: SearchBarViewController {

   override func viewDidLoad() {
      super.viewDidLoad()
      constructSearchBar()
   } 
 }

Regarding to emrys57's answer, I tried adding viewWillAppear() in my ViewController but I couldn't make it work, as my cancel looks a little different:

override func viewWillAppear(animated: Bool) {
    super.viewDidAppear(animated)

    // Here, I couldn't figure out what to put because
    // my searchBarCancelButtonClicked() needs searchBar and
    // forces me to use (!) but then it says, it's optional..
}

The answer is...

 override func viewWillAppear(animated: Bool) {
    super.viewDidAppear(animated)
    navigationItem.titleView = nil
    constructSearchBar()
 }

Upvotes: 0

Views: 202

Answers (1)

emrys57
emrys57

Reputation: 6806

You have not posted code, so it's not entirely clear what's gone wrong. Using UISearchBar, I think you must be handling the buttons separately yourself, as opposed to using UISearchController. I think that you may not be clearing away the search bar when coming back from the second VC. This code clears out the search bar in viewWillAppear:

class ViewController: UIViewController {

var cancelButton: UIBarButtonItem?
var searchButton: UIBarButtonItem?

override func viewDidLoad() {
    super.viewDidLoad()
    cancelButton = UIBarButtonItem(barButtonSystemItem: .Cancel, target: self, action: Selector("searchCancelPressed:"))
    searchButton = UIBarButtonItem(barButtonSystemItem: .Search, target: self, action: Selector("searchPressed:"))
}

override func viewWillAppear(animated: Bool) {
    super.viewDidAppear(animated)
    searchCancelPressed(nil)
}

func searchPressed(sender: AnyObject) {
    navigationItem.titleView = UISearchBar()
    navigationItem.rightBarButtonItem = cancelButton
}

func searchCancelPressed(sender: AnyObject?) {
    navigationItem.titleView = nil
    navigationItem.rightBarButtonItem = searchButton
}

}

and that is working nicely for me when I do a push from a button to the second VC and then hit back.

Following the edit to the original question, this code seems to work, although it may not be the most elegant way of constructing the answer:

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    navigationItem.titleView = nil
    searchBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Search, target: self, action: "showSearchBar")
    navigationItem.rightBarButtonItem = searchBarButtonItem
}

The function constructSearchBar no longer needs to be called in viewDidLoad, and can be deleted.

Upvotes: 1

Related Questions