如何将UISearchController放置到navigationTitle以及如何通过按钮启用和禁用它?

时间:2018-02-07 19:45:08

标签: swift search uisearchbar uisearchcontroller

我是Swift的新手,想知道是否有可能将UIsearchcontroller放在navgationtitle中,并通过按钮(位于navigationRightItem)隐藏和取消隐藏uisearchcontroller。 我已经看到很多将UISearchBar从Object库放到navigationTitle的例子,但是没有uisearchcontroller的例子。有人甚至说ios10 Swift已经弃用了来自对象库的UISearch栏。 请澄清弃用以及为什么我不应该从对象库中使用UISearchBar。 哪一个是用于firebase tableview搜索的最佳实践。 如果您能够提供代码示例,我将很高兴。 提前谢谢。

1 个答案:

答案 0 :(得分:2)

<强>的UISearchBar

UISearchBar尚未弃用。 UISearchBar是一个UIView,您可以将其放置在任何您想要的位置,包括导航栏,如果这是您想要的,也可以放在屏幕中间。您可以以编程方式执行此操作,也可以使用Interface Builder拖动搜索栏并将其放在一个视图中。

使用UISearchBar

实现搜索的一种方法是使用UISearchBar,将其放在navigationItem.titleView中,并将视图控制器设置为此搜索栏的委托。当用户与搜索栏交互时,会通知您的视图控制器,您必须在同一个视图控制器中处理搜索逻辑。例如,您可能需要检测搜索是否处于活动状态以决定用于表视图的数据源 - 如果搜索未激活,则显示所有项目;如果搜索处于活动状态,则只显示项目的子集。或者您可能希望为主视图显示一个布局,为搜索结果显示不同的布局。同样,您必须在视图控制器中处理此逻辑。这是UISearchController派上用场的地方!

使用UISearchController

UISearchController是一个UIViewController,为您提供UISearchBar。 UISearchController很有用,因为它可以帮助您在新的视图控制器中显示搜索结果,使您的搜索逻辑与主逻辑分开。 要解决问题中的特定点,请记住,您放在navigationItem.titleView中的内容是UISearchBar,而不是UISearchController。您可以自己创建此UISearchBar,也可以创建UISearchController并使用其搜索栏(searchController.searchBar)。

使用navigationItem.searchController属性将UISearchBar放置在navigationItem.titleView VS中

将您的UISearchBar放置在navigationItem.titleView中是多个应用程序中使用的常见模式。但是,在iOS 11中,Apple引入了navigationItem.searchController属性。这里没有什么可以弃用的,但是当在导航栏中使用搜索栏时,Apple似乎更喜欢我们这样做。

下面是一个如何运作的例子。

Using navigationItem.searchController property and a UISearchController to manage display of search results

您的主视图控制器:

class HomeViewController: UIViewController {
   (…)

    override func viewDidLoad() {
        (…)

        // Get the view controller that will be used to present search results.
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        guard let languagesSearchResultsViewController = storyboard.instantiateViewController(withIdentifier: "LanguagesSearchResultsViewController") as? LanguagesSearchResultsViewController else { return }

        // Create a search controller and initialize it with the view controller that will be used to show the search results
        let searchController = UISearchController(searchResultsController: languagesSearchResultsViewController)

        // The searchResultsUpdater is the object that will be notified when the user performs a search.
        // I'm setting it to be the view controller that will present the results but is doesn't have to be.
        searchController.searchResultsUpdater = languagesSearchResultsViewController

        // Set the searchController property in the navigationItem and a search bar will automagically appear in the navigation bar, below the title.
        navigationItem.searchController = searchController
        definesPresentationContext = true

        (…)        
    }
}

您将用于显示搜索结果的视图控制器:

class LanguagesSearchResultsViewController: UIViewController {

    // MARK: - Properties

    // Complete list of items to search. If you're doing a network request for your search term then you don't need this.
    let languages = ["Mandarin Chinese", "English", "Hindustani", "Spanish", "Arabic", "Malay", "Russian", "Bengali", "Portuguese", "French", "Hausa", "Punjabi", "German", "Japanese", "Persian", "Swahili", "Telugu", "Javanese", "Wu Chinese", "Korean"]

    // The data source for your search results
    var searchResults: [String] = []

    // MARK: - IBOutlets

    @IBOutlet weak var tableView: UITableView!

    // MARK: - UIViewController methods

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.dataSource = self
    }

   (…)
}

// MARK: - UISearchResultsUpdating

extension LanguagesSearchResultsViewController: UISearchResultsUpdating {
    func updateSearchResults(for searchController: UISearchController) {
        guard let searchText = searchController.searchBar.text else { return }
        searchResults = languages.filter { $0.contains(searchText) }
        tableView.reloadData()
    }
}

// MARK: - UITableViewDataSource

extension LanguagesSearchResultsViewController: UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return searchResults.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "LanguageTableViewCell") as? LanguageTableViewCell else { return UITableViewCell() }

        let language = searchResults[indexPath.row]

        cell.languageNameLabel.text = language
        return cell
    }
}

如果您仍然希望titleView中的搜索栏具有您描述的显示/隐藏行为,则无论是否使用UISearchController,您都需要更多自定义内容。其他问题已经有很多答案可以帮助你做到这一点。希望这有助于澄清您的选择。