如何过滤表视图中的部分行?

how to filter section wise row in tableview?

我是 iOS 的新手,正在根据 JSON 响应创建演示应用程序。

我的查询是我不知道如何明智地编写和过滤行数据部分以在 tableview 上显示。

category.json [文件]

{
    "category": [
        {
            "vName": "Section 0",
            "skill": [
                {
                    "vName": "Section 0 Row 1",
                },
                {
                    "vName": "Section 0 Row 2",
                }
            ]
        },
        {
            "vName": "Section 1",
            "skill": [
                {
                    "vName": "Section 1 Row 1",
                },
                {
                    "vName": "Section 1 Row 2",
                }
            ]
        },
        {
            "vName": "Section 2",
            "skill": [
                {
                    "vName": "Section 2 Row 1",
                },
                {
                    "vName": "Section 2 Row 2",
                }
            ]
        },
        {
            "vName": "Section 3",
            "skill": [
                {
                    "vName": "Section 3 Row 1",
                },
                {
                    "vName": "Section 3 Row 2",
                }
            ]
        }
    ]
}

Response.Swift [文件]

//
//  Response.swift
//  SectionTableSearchDemo
//

import Foundation
struct Welcome: Codable {
    let category: [Category]
}

struct Category: Codable {
    let vName: String
    let skill: [Skill]

    enum CodingKeys: String, CodingKey {
        case vName,skill
    }
}

struct Skill: Codable {
    let vName: String

    enum CodingKeys: String, CodingKey {

        case vName
    }
}

#SectionTableviewController.swift [文件]

//
//  SectionTableViewController.swift
//  SectionTableSearchDemo
//

import UIKit


class SectionTableViewController: UITableViewController, UISearchResultsUpdating {

    var cat : Welcome?
    var searchController : UISearchController!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        parseJSON()
        searchControllerSetup()
    }

     private func searchControllerSetup(){
        
        searchController = UISearchController(searchResultsController: nil)
        searchController.searchResultsUpdater = self
    
        navigationItem.searchController = searchController
        navigationItem.hidesSearchBarWhenScrolling = false
    }
    
    // i don't know how to implement and show only skills when search
    func updateSearchResults(for searchController: UISearchController) {
        
    }
    
    private func parseJSON(){
        
        guard let path = Bundle.main.path(forResource: "category", ofType: "json")else{
            return
        }
       
        let url = URL(fileURLWithPath: path)
        
        do {
            let jsonData = try Data(contentsOf: url)
            cat = try JSONDecoder().decode(Welcome.self, from: jsonData)
            if let result = cat {
                print(result)
            }
        } catch  {
            print("Error is \(error)")
        }
        
        
    }
    
    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return  (cat?.category.count)!
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        if let cat = cat {
            return cat.category[section].skill.count
        }else{
            return 0
        }
    }

    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

        let text = cat?.category[indexPath.section].skill[indexPath.row].vName
        cell.textLabel?.text = text

        return cell
    }
    
    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        let titleText = cat?.category[section].vName
        return titleText
    }
    /*
    // Override to support conditional editing of the table view.
    override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        // Return false if you do not want the specified item to be editable.
        return true
    }
    */

    /*
    // Override to support editing the table view.
    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            // Delete the row from the data source
            tableView.deleteRows(at: [indexPath], with: .fade)
        } else if editingStyle == .insert {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        }    
    }
    */

    /*
    // Override to support rearranging the table view.
    override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {

    }
    */

    /*
    // Override to support conditional rearranging of the table view.
    override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
        // Return false if you do not want the item to be re-orderable.
        return true
    }
    */

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }
    */

}


和我的形象what I did

请大家帮我想想办法

谢谢

要在模型中搜索数据,您可以使用过滤器功能。 与在 tableview 单元格中显示数据的方式相同。您可以使用过滤功能进行搜索,并根据搜索标志显示其中的数据。

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {

        guard let searchText = searchText, !searchText.isEmpty else {
            return
        }

        searchData = cat?.category.map({
                        [=10=].skill.filter({[=10=].vName == searchText})
                           }).filter({ [=10=].count > 0 })

        searching = true
        self.searchedSkillsResults = searchData
        tableView.reloadData()
    }

//如果您的搜索为真,请在此处检查并显示技能数组,否则搜索为假的原始数组结果。

参考link:

//下面link 帮助您在嵌套数组中搜索。

我正在运行的示例代码:

import Foundation
struct Welcome: Codable {
   let category: [Category]
}

struct Category: Codable {
    let vName: String
    let skill: [Skill]

    enum CodingKeys: String, CodingKey {
        case vName,skill
    }
}

struct Skill: Codable {
    let vName: String

    enum CodingKeys: String, CodingKey {

         case vName
    }
 }

 var cat : Welcome?

 private func parseJSON(){

    guard let path = Bundle.main.path(forResource: "category", ofType: 
        "json")else{
        return
    }

    let url = URL(fileURLWithPath: path)

    print(url)

    do {
        let jsonData = try Data(contentsOf: url)
        cat = try JSONDecoder().decode(Welcome.self, from: jsonData)
        if let result = cat {
             print(result)
        }
    } catch  {
        print("Error is \(error)")
    }
}

parseJSON()
//print(cat)

let searchText = "Section 0 Row 1"
let result = cat?.category.map({
   [=11=].skill.filter({[=11=].vName.lowercased().contains(searchText.lowercased())})
}).filter({ [=11=].count > 0 })

//output = Optional([[Skill(vName: "Section 0 Row 1")]])

像下面这样尝试。

添加如下两个变量。

var filteredProducts = [Category]()
var products: [Category] = []

并初始化产品变量

///......
let jsonData = try Data(contentsOf: url)
cat = try JSONDecoder().decode(Welcome.self, from: jsonData)

products = cat.category // add this line

现在修改table查看数据源如下

// MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        if searchController.isActive && searchController.searchBar.text != "" {
             return filteredProducts.count
        }
        return products.count
    }

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        if searchController.isActive && searchController.searchBar.text != "" {
             return filteredProducts[section].skill.count
        }else{
            return products[section].skill.count
        }
    }

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        let product: Category
        if searchController.isActive && searchController.searchBar.text != "" {
            product = filteredProducts[indexPath.row]
        } else {
            product = products[indexPath.row]
        }

        let text = product.skill[indexPath.row].vName
        cell.textLabel?.text = text

        return cell
    }
    
    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        let product: Category
        if searchController.isActive && searchController.searchBar.text != "" {
            product = filteredProducts[indexPath.row]
        } else {
            product = products[indexPath.row]
        }
        let titleText = product[section].vName
        return titleText
    }

然后创建一个函数来过滤您的数据


func filterContentForSearchText(_ searchText: String) {
        filteredProducts = products.filter({( product : Category) -> Bool in
            return product.title!.lowercased().contains(searchText.lowercased())
        })
        yourTableView.reloadData() // reload your table view
}

致电filterContentForSearchText()


func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
     filterContentForSearchText(searchBar.text!)
}

func updateSearchResults(for searchController: UISearchController) {
     filterContentForSearchText(searchController.searchBar.text!)
}