无法将 UISearchController 搜索栏添加到导航栏中,并且未调用委托方法

Posted

技术标签:

【中文标题】无法将 UISearchController 搜索栏添加到导航栏中,并且未调用委托方法【英文标题】:Unable to add UISearchController's search bar into navigationbar and delegate methods not getting called 【发布时间】:2019-04-04 04:54:30 【问题描述】:

我想实现一些非常简单的东西:导航栏中的搜索栏,带有一个取消按钮,当栏被激活时显示。

我正在使用UISearchController,目前我有以下内容:

override func viewDidLoad() 
  super.viewDidLoad()
  ...

  let searchController = UISearchController(searchResultsController: nil)
  searchController.searchResultsUpdater = self
  searchController.delegate = self
  searchController.searchBar.delegate = self
  searchController.hidesNavigationBarDuringPresentation = false
  searchController.searchBar.sizeToFit()
  self.navigationItem.titleView = searchController.searchBar
  self.definesPresentationContext = true

搜索栏显示。但是,如果我专注于它,则不会显示“取消”按钮,也不会调用任何委托方法。也就是说,不会调用UISearchResultsUpdatingUISearchControllerDelegateUISearchBarDelegate 协议中的任何方法,尽管我已将self 设置为响应所有这些方法。

如果我将以下行放入viewDidLoad,则委托方法开始起作用:

self.navigationItem.searchController = searchController

但是,我不能将搜索栏放在导航栏中。它显示在导航栏下方。

我在 SO 中进行了广泛的搜索,但似乎没有什么对我有用。我可能在这里遗漏了一些明显的东西 - 我怎样才能让它工作?谢谢!

【问题讨论】:

确保您在课堂上扩展了所需的代表。是的,搜索栏显示在导航栏下方,但它在导航栏内......就像原生设置应用程序一样。 @dahiya_boy 谢谢我确实扩展了代表。是的,从技术上讲,它在导航栏内——我希望它看起来像 Instagram 或 Twitter,即它是一排(44pt),只有搜索栏。 请添加您预期的屏幕图像以及您现在得到的内容.. 我想要类似于***.com/questions/26726520/… 中的内容。但我的主要问题是没有触发任何委托方法。 【参考方案1】:

只需将UISearchController 定义为属性,然后一切正常。

我在下面的示例项目中进行了测试。

  class ViewControllerName: UIViewController
       let searchController = UISearchController(searchResultsController: nil)

        override func viewDidLoad() 
            super.viewDidLoad()
            let search = UISearchController(searchResultsController: nil)
            self.navigationItem.searchController = search
            self.navigationItem.searchController!.searchBar.delegate = self
            self.navigationItem.searchController!.searchResultsUpdater = self
            self.navigationItem.searchController?.searchBar.showsCancelButton = true
        

       func searchBarTextDidEndEditing(_ searchBar: UISearchBar) 
            print("Called")
        

        func updateSearchResults(for searchController: UISearchController) 
            print("Called")
        
    

希望它对你有用。

【讨论】:

有预定义的委托规则,例如,如果你在 View 或 ViewController 中以编程方式添加一些东西并且你想分配任何委托然后定义为属性,因为有时会遇到像你这样的问题,在其余情况下它会起作用.很高兴听到为你工作。快乐编码 您能否更改您的问题标题“无法将 UISearchController 的搜索栏放入导航栏”(例如未调用委托或其他)我认为这不合适。正确的标题也适用于其他人。 这实际上是一个正确的标题。正如我在问题中所描述的,如果我不将搜索栏放在导航栏中,它就可以正常工作。只有当我像这样将它放入导航栏中时,它才停止工作。再次感谢!【参考方案2】:

我已经尝试过这段代码和一切正常的道具

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate, UISearchResultsUpdating 


@IBOutlet weak var tblView: UITableView!


override func viewDidLoad() 
    super.viewDidLoad()
    :
    :

    let search = UISearchController(searchResultsController: nil)
    self.navigationItem.searchController = search
    self.navigationItem.searchController!.searchBar.delegate = self
    self.navigationItem.searchController!.searchResultsUpdater = self
    self.navigationItem.searchController?.searchBar.showsCancelButton = true

    :
    :

在委托下测试,两者都按预期调用。

func searchBarTextDidEndEditing(_ searchBar: UISearchBar) 
    print("search end editing.")


func updateSearchResults(for searchController: UISearchController) 
    print("update search results ... called here")

用户界面:

【讨论】:

谢谢!这是我想要避免的——你可以看到如果这样做,搜索栏上方会有一个“不可见的导航栏”。上面的答案对我有用。【参考方案3】:

调用这个

self.navigationItem.titleView = searchController.searchBar

来自 viewWillAppear(),而不是来自 viewDidLoad()。并且委托方法工作正常。

【讨论】:

以上是关于无法将 UISearchController 搜索栏添加到导航栏中,并且未调用委托方法的主要内容,如果未能解决你的问题,请参考以下文章

UISearchController 搜索栏无法激活

在 UISearchController 中搜索时无法在 tableView 中滚动

从 UISearchController Swift 传递更多数据

如何将 UISearchController 搜索栏设置为不是 tableHeaderView 或 navigationItem.titleview 的视图?

UISearchController:昏暗的覆盖覆盖搜索栏本身

UISearchController 禁用取消 UIBarButtonItem