【问题标题】:How is UISearchController meant to be used without UINavigationController?UISearchController 是如何在没有 UINavigationController 的情况下使用的?
【发布时间】:2020-10-21 09:42:04
【问题描述】:

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

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

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

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

【问题讨论】:

  • 如果我没记错的话,你可以在没有导航栏的情况下使用UISearchBar
  • 在我看来你别无选择。除非在导航控制器中,否则无法使用 UISearchController
  • 我制作了一个示例应用程序。实际上,您不需要导航控制器。你确实需要一个表格视图。否则搜索控制器将永远不会出现。
  • @ElTomato 我可以看到代码吗?是在 GitHub 上吗?或者您可以将其粘贴到下面的答案中吗?
  • 给我 15 分钟。

标签: ios swift uinavigationcontroller uikit uisearchcontroller


【解决方案1】:

你可能想多了。你可以很好地使用没有导航控制器或表格视图的 UISearchController。人们使用表格视图的唯一原因是有一些显示搜索结果的方式很好。但是 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 的作用,即几乎没有。它只是通过放置辅助视图控制器并在用户在搜索栏中键入时发出信号来响应用户在搜索栏中的点击。其他一切由您决定。

【讨论】:

  • 我喜欢这个例子,因为它非常简单并且使用了单独的搜索结果控制器。但是我注意到您仍然必须主动将搜索栏添加到视图中。在下面的@El Tomato 回答中,您不必这样做。或者,当您使用 UINavigationController 时,您不必这样做。我仍然不明白其中的区别。
  • 你错了。您总是必须将搜索控制器的搜索栏添加到界面中。也许您看不到在其他示例中这样做的地方,但我看到了。例如,在 el 番茄的回答中,即tableView.tableHeaderView = searchController.searchBar 行。
  • 嗯,非常正确。虽然我没有看到它在我链接的苹果示例代码中添加的位置 - developer.apple.com/documentation/uikit/view_controllers/…。这是因为导航控制器自动将其 navigationItem 视图设置为 searchControllers 的搜索栏吗?
  • 是的,完全正确。过去,您实际上也必须在那里添加搜索栏,但后来他们发明了导航项链接作为快捷方式。但结果是一样的:搜索控制器的搜索栏进入界面。否则就没有意义了!
【解决方案2】:

我有一个简单的 Xcode 项目,其中主视图控制器 (UIViewController) 有一个表格视图 (UITableView) 及其关联的表格单元格 (UITableViewCell)。故事板没有导航控制器。视图控制器 (UIViewController) 带有一个表视图 (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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-12
    • 2016-02-23
    • 2013-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多