在导航栏上使用返回错误 UIBarButtonItem

Using Back on Navigation Bar bugs UIBarButtonItem

我在 TableView 的顶部有一个 NavigationBar。看起来不错 opening/closing 搜索。


但是,如果我单击单元格中的按钮并被定向到另一个页面(使用 segue);然后使用后退按钮放松,好像有问题。

()

所以它看起来像是被按下并打开了,但它不应该。它应该看起来像顶部图片(只是 UIBarButtonItem - 搜索按钮)


我无法弄清楚造成此问题的原因。

请注意 < Back 是自动创建的,我没有编写任何代码来创建它。我做错了什么吗?


更新: 添加了一些片段...

首先,创建了一个不同的 class 来处理搜索

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

还有我的ViewController:

 class ViewController: SearchBarViewController {

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

关于 emrys57 的回答,我尝试在我的 ViewController 中添加 viewWillAppear() 但我无法让它工作,因为我的取消看起来有点不同:

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..
}

答案是...

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

您还没有发布代码,所以还不完全清楚哪里出了问题。使用 UISearchBar,我认为您必须自己单独处理按钮,而不是使用 UISearchController。我认为您从第二个 VC 返回时可能不会清除搜索栏。此代码清除 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
}

}

当我从一个按钮按到第二个 VC 然后点击 back 时,这对我来说效果很好。

在对原始问题进行编辑之后,这段代码似乎有效,尽管它可能不是构建答案的最优雅方式:

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

函数constructSearchBarviewDidLoad中不再需要调用,可以删除。