TableViewController 在搜索时填充,但不会加载初始视图

Posted

技术标签:

【中文标题】TableViewController 在搜索时填充,但不会加载初始视图【英文标题】:TableViewController populates on search, but won't load initial view 【发布时间】:2019-07-28 05:19:43 【问题描述】:

Swift 5、ios 12、Xcode 10

我终于在我的 ListingsViewController 上实现了一个搜索栏,它工作得非常好——但初始数据没有填充到表格中。

我意识到这是一个笨拙的实现,但我边走边学,而且我只使用我能理解的代码。我已经做了两天了——我尝试创建一个 Struct 并以这种方式引入数据,但我什至无法获得一个 Array。我尝试将它作为 NSArrayArrayObject 引入,但要么我无法加载初始表,或者我根本无法解析出数据,或者无法进行搜索。

我怀疑这与我调用 loadData() 函数的方式、时间或地点有关,但我无法弄清楚。

class ListingsViewController: UITableViewController, UISearchResultsUpdating  
    var tableData = [String]()
    var filteredTableData = [String]()
    var resultSearchController = UISearchController()
    func updateSearchResults(for searchController: UISearchController) 
        filteredTableData.removeAll(keepingCapacity: false)
        let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %@", searchController.searchBar.text!)
        let array = (tableData as NSArray).filtered(using: searchPredicate)
        filteredTableData = array as! [String]
        self.tableView.reloadData()
    
    override func viewDidAppear(_ animated: Bool) 
        super.viewDidAppear(true)
        tableData = [String]()
        loadData()
    
    override func viewDidLoad() 
        super.viewDidLoad()
        tableView.reloadData()
        resultSearchController = (
            let controller = UISearchController(searchResultsController: nil)
            controller.searchResultsUpdater = self
            controller.dimsBackgroundDuringPresentation = false
            controller.searchBar.sizeToFit()
            tableView.tableHeaderView = controller.searchBar
            return controller
        )()
        tableView.reloadData()
    
    func loadData() 
        guard let url = URL(string: "--------------") else return  
        let task = URLSession.shared.dataTask(with: url)  (data, response, error) in
            guard let dataResponse = data, error == nil else 
                print(error?.localizedDescription ?? "Response Error")
                return
            
            do 
                let jsonResponse = try JSONSerialization.jsonObject(with: dataResponse, options: [])
                guard let jsonArray = jsonResponse as? [[String:Any]] else  return 
                for dic in jsonArray 
                    self.tableData.append(dic["name"] as! String)
                    //                    self.feedItems.append(Listing(id: (dic["id"] as! String), city_id: (dic["city_id"] as! String), category: (dic["category"] as! String), sub_category: (dic["sub_category"] as! String), name: (dic["name"] as! String), phone: (dic["phone"] as! String), email: (dic["email"] as! String), website: (dic["website"] as! String), address: (dic["address"] as! String), comment: (dic["comment"] as! String), recommendedby: (dic["recommendedby"] as! String)))
                
             catch let parsingError 
                print("Error", parsingError)
            
        
        self.tableView.reloadData()
        task.resume()
    
    override func numberOfSections(in tableView: UITableView) -> Int 
        return 1
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        if (resultSearchController.isActive) 
            return filteredTableData.count
         else 
            return tableData.count
        
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        cell.textLabel?.textColor = .white
        cell.backgroundColor = .black
        cell.tintColor = .lightText
        if (resultSearchController.isActive) 
            cell.textLabel?.text = filteredTableData[indexPath.row]
            return cell
         else 
            cell.textLabel?.text = tableData[indexPath.row]
            return cell
        
    

当我从标签栏切换到 ListingsViewController 时,我希望会出现整个列表。相反,我得到一张空白表。

但是,如果我点击搜索栏并开始输入,我会得到匹配的结果 - 当我取消搜索时,我可以在表格中看到所有结果。

(另外,当我点击搜索栏时,我的导航栏会消失并且不会返回,即使我取消搜索也是如此。即使我切换到其他标签并返回。无法弄清楚这一点。)

【问题讨论】:

你设置好数据源和委托给tableView了吗 @kjoe 是的,谢谢——我将它们设置在情节提要中。我还在代码中的viewDidAppear 函数中尝试过它们。 【参考方案1】:

您缺少表视图的委托和数据源 添加这个:

class ListingsViewController: UITableViewController, UISearchResultsUpdating,UITableViewDelegate,UITableViewDataSource 
//your class code here

并在您的viewDidLoad 上添加:

self.tableView.delegate = self
self.tableView.dataSource = self

这应该可以,请注意,在您调用委托和数据源后,您的单元格的行数和行数函数将被调用,因此请确保您使用的数组届时不为零

【讨论】:

谢谢,但这会引发我预期会得到的两个错误:Redundant conformance of 'ListingsViewController' to protocol 'UITableViewDelegate'Redundant conformance of 'ListingsViewController' to protocol 'UITableViewDataSource'。这是UITableViewController,所以如果我将其声明为dataSourcedelegate,它会失败。 我在loadData() 调用之后的viewDidLoad() 中添加了这两行,但它没有改变任何东西。 @JoshGoldwasser 你已经符合协议,按下红色错误并让Xcode完成协议,你需要在section方法中添加行和行数的单元格。【参考方案2】:

我看到您没有缺少表视图的委托和数据源。 您必须为 viewcontroler 注册委托和数据源。您将在哪里显示数据。

请将此代码插入您的 viewDidLoad

self.tableView.delegate = self

self.tableView.dataSource = self

【讨论】:

您好,谢谢您 — 但这不起作用。添加这两行并没有改变任何东西。【参考方案3】:

将您的加载日期更改为此

func loadData() 
        guard let url = URL(string: "--------------") else’s  return  
        let task = URLSession.shared.dataTask(with: url)  (data, response, error) in
            guard let dataResponse = data, error == nil else 
                print(error?.localizedDescription ?? "Response Error")
                return
            
            do 
                let jsonResponse = try JSONSerialization.jsonObject(with: dataResponse, options: [])
                guard let jsonArray = jsonResponse as? [[String:Any]] else  return 
                for dic in jsonArray 
                    self.tableData.append(dic[“name”] as! String
                


            DispatchQueue.main.async 
                    print("call to reload data")
                    self.tableView.reloadData()
                
             catch let parsingError 
                print("Error", parsingError)
            
        

        task.resume()
    

您需要在完成块之前重新加载数据,您可以使用以下print("calling to reloadData") 检查它然后测试我的解决方案并查看它是否有效,为JsonArray 制作打印状态以检查调用的位置,您必须重新加载async func终止后的tableViewData。

【讨论】:

以上是关于TableViewController 在搜索时填充,但不会加载初始视图的主要内容,如果未能解决你的问题,请参考以下文章

UISearchBar 不在 TableViewController 的表视图标题中?

segue 将数据从 tableviewcontroller 解析到另一个

UISearchBar 和 TableViewController

Swift - 在自定义 TableViewController 中出现 SearchBar 问题

选择行时 TableViewController 中的两个动画

如何将 Firebase iOS 中的数据从 TableViewController 传递到另一个 ViewController