在没有 UINavigationController 的情况下如何使用 UISearchController?

How is UISearchController meant to be used without UINavigationController?

当视图控制器未嵌入 UINavigationController 时,我不明白如何使用 UISearchController。

为了说明我的意思,请尝试下载此代码:https://developer.apple.com/documentation/uikit/view_controllers/displaying_searchable_content_by_using_a_search_controller

然后,删除导航控制器并使 Table 搜索场景成为初始视图控制器。 table 仍然正常工作,但搜索控制器没有出现。

有没有办法修改该代码,以便您可以在不将 UISearchController 嵌入导航控制器的情况下使用它?我在需要 UINavigationController 的文档中没有看到任何内容。所有关于此的堆栈溢出问题都会告诉您单独使用 UISearchBar。我对使用 UISearchController 特别感兴趣。

我有一个简单的 Xcode 项目,其中主视图控制器 (UIViewController) 有一个 table 视图 (UITableView) 及其关联的 table 单元格 (UITableViewCell)。故事板没有导航控制器。视图控制器 (UIViewController) 带有一个 table 视图 (UITableView)。

// ViewController
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchResultsUpdating {
    // MARK: - Variables
    var users = [[String : Any]]()
    let searchController = UISearchController(searchResultsController: nil)
    
    
    // MARK: - IBOutlet
    @IBOutlet weak var tableView: UITableView!
    
    
    // MARK: - Life cycle
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let user0 = ["name": "Jim", "age": 54, "ID": UUID().uuidString] as [String : Any]
        let user1 = ["name": "Katherine", "age": 44, "ID": UUID().uuidString] as [String : Any]
        let user2 = ["name": "Susan", "age": 28, "ID": UUID().uuidString] as [String : Any]
        let user3 = ["name": "Nancy", "age": 36, "ID": UUID().uuidString] as [String : Any]
        let user4 = ["name": "Georege", "age": 21, "ID": UUID().uuidString] as [String : Any]
        let user5 = ["name": "Arnold", "age": 68, "ID": UUID().uuidString] as [String : Any]
        let user6 = ["name": "Tom", "age": 33, "ID": UUID().uuidString] as [String : Any]
        let user7 = ["name": "Jerry", "age": 25, "ID": UUID().uuidString] as [String : Any]
        let user8 = ["name": "Kate", "age": 40, "ID": UUID().uuidString] as [String : Any]
        let user9 = ["name": "Austin", "age": 72, "ID": UUID().uuidString] as [String : Any]
        users.append(user0)
        users.append(user1)
        users.append(user2)
        users.append(user3)
        users.append(user4)
        users.append(user5)
        users.append(user6)
        users.append(user7)
        users.append(user8)
        users.append(user9)
        
        searchController.searchResultsUpdater = self
        searchController.hidesNavigationBarDuringPresentation = false
        //searchController.dimsBackgroundDuringPresentation = false
        tableView.tableHeaderView = searchController.searchBar
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
    }
    
    
    // MARK: - IBOutlet
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return users.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MyTableViewCell
        let user = users[indexPath.row]
        let name = user["name"] as! String
        let age = user["age"] as! Int
        let id = user["ID"] as! String
        cell.nameField.text = name
        cell.ageField.text = String(age)
        cell.nameField.tag = 0
        cell.ageField.tag = 1
        cell.nameField.accessibilityIdentifier = id
        cell.ageField.accessibilityIdentifier = id
        
        cell.onEditingName = { id in
            print(id)
        }
        cell.onEditingAge = { id in
            print(id)
        }
        
        return cell
    }
    
    func updateSearchResults(for searchController: UISearchController) {
        
    }
}

// MyTableViewCell.swift
import UIKit

class MyTableViewCell: UITableViewCell {
    @IBOutlet weak var nameField: UITextField!
    @IBOutlet weak var ageField: UITextField!
    
    @IBAction func nameEditingDidEnd(_ sender: UITextField) {
        onEditingName!(sender.accessibilityIdentifier!)
    }
    
    @IBAction func ageEditingDidEnd(_ sender: UITextField) {
        onEditingAge!(sender.accessibilityIdentifier!)
    }
    
    override func awakeFromNib() {
        super.awakeFromNib()
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }
    
    var onEditingName: ((String) -> Void)?
    var onEditingAge: ((String) -> Void)?
}

完整的项目文件位于 GitHub

你可能想多了。您可以完美地使用没有导航控制器或 table 视图的 UISearchController。人们使用 table 视图的唯一原因是可以通过某种方式显示搜索结果。但是 UISearchController 是一个非常普通的视图控制器,并且无论如何都会完成它的工作。这真的是世界上最简单的事情——这就是它的美妙之处。它非常简单,任何关于搜索的

这是我能想到的最微小的例子。这基本上是应用程序的全部代码:

class ViewController: UIViewController {
    var sc : UISearchController?
    override var prefersStatusBarHidden: Bool { true }
    override func viewDidLoad() {
        super.viewDidLoad()
        let vc2 = ViewController2()
        let sc = UISearchController(searchResultsController: vc2)
        self.sc = sc
        sc.searchResultsUpdater = vc2
        let sb = sc.searchBar
        self.view.addSubview(sb)
    }
}
class ViewController2: UIViewController, UISearchResultsUpdating {
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .green
    }
    func updateSearchResults(for searchController: UISearchController) {
        guard searchController.isActive else {return}
        if let t = searchController.searchBar.text, !t.isEmpty {
            print("You are searching for", t)
        }
    }
}

这完美地说明了 UISearchController 所做的事情,即几乎没有。当用户在搜索栏中输入时,它只是通过放置一个辅助视图控制器并发出信号来响应用户在搜索栏中的点击。其他一切由你决定。