Как реализовать панель поиска TextField для фильтрации значений таблицы просмотра Swift - PullRequest
0 голосов
/ 12 февраля 2020

Я создал пользовательскую панель textField поверх ViewController для фильтрации значений данных в UITableView. Поскольку у меня есть вложенный тип JSON, я не мог правильно понять, как использовать фильтр для него.

  • Я хочу реализовать textField в качестве панели поиска с помощью TableView. скриншот прилагается.
  • Значение, которое мне нужно отфильтровать, - это pickList -> textField
  • textSearchChange функция, добавленная для текстового поиска.

Данные разделены на части, а затем значения и уже отображаются в tableView.

Модель:

struct SectionList : Codable {

    let title : String?
    var items : [Item]?

}

struct PickListData: Codable {
    let items: [Item]?
}

struct Item : Codable {

    let actionType : Int?
    var textField : String?
    var pickList: [SectionList]?
    var selection: [Item]?
    let selectedValue: [String]?
    let version: Int?
    let masterId: Int?
    let itemValue: String?
}

Код ViewController:

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet weak var searchTxt: UITextField!
    @IBOutlet weak var tableView: UITableView!
    var AppData: Item?
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        tableView.delegate = self
        tableView.dataSource = self
        searchTxt.delegate = self
        readDataList()
    }
    func readDataList(){

        if let url = Bundle.main.url(forResource: "list", withExtension: "json") {
            do {

                let data = try Data(contentsOf: url)
                let decoder = JSONDecoder()
                let response = try decoder.decode(PickListData.self, from: data)
                let res = response.items?.filter { $0.actionType == 101}
                AppData = res?.first
                print(AppData)
                self.tableView.reloadData()
            } catch {
                print("error:\(error)")
            }
        }

    }

    @IBAction func textSearchChange(_ sender: UITextField) {
        print("search")
    }


}

extension ViewController: UITableViewDelegate, UITableViewDataSource {

    func numberOfSections(in tableView: UITableView) -> Int {
        return AppData?.pickList?.count ?? 0
        }

    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return AppData?.pickList?[section].title
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return AppData?.pickList?[section].items?.count ?? 0
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell()
        let dic = AppData?.pickList?[indexPath.section].items?[indexPath.row]//.pickList?[indexPath.row].title
            //AppData?[indexPath.section].pickList[indexPath.row].items
        //print(dic)

        cell.textLabel?.text = dic?.textField
        return cell
    }

}

JSON Данные:

{
  "items": [
    {
      "actionType": 101,
      "version": 3,
      "pickList": [
        {
          "title": "Sayaç yeri seçimi",
          "items": [
            {
              "textField": "Sayaç Yeri Seçiniz",
              "itemValue": "0"
            },
            {
              "textField": "Sayaç daire girişinde",
              "itemValue": "1"
            },
            {
              "textField": "Sayaç apt. girişinde",
              "itemValue": "2"
            },
            {
              "textField": "Sayaç bodrumda",
              "itemValue": "3"
            },
            {
              "textField": "Sayaç çatı katında",
              "itemValue": "4"
            },
            {
              "textField": "Sayaç bahçede (Müstakil)",
              "itemValue": "5"
            },
            {
              "textField": "Sayaç bina dışında",
              "itemValue": "6"
            },
            {
              "textField": "Sayaç balkonda",
              "itemValue": "7"
            },
            {
              "textField": "Sayaç daire içinde",
              "itemValue": "8"
            },
            {
              "textField": "Sayaç istasyon içinde",
              "itemValue": "9"
            }
          ]
        }
      ]
    }
]
}

Обновленный код: но это неправильно. Я хочу искать с помощью TextField

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        let searchText  = textField.text! + string

        Filterdata = (AppData?.pickList?.filter({(($0.title!).localizedCaseInsensitiveContains(searchText))}))!

         if(Filterdata.count == 0){
           isSearch = false
         }else{
           isSearch = true
        }
         self.tableView.reloadData();

         return true
    }

Изображение: searchTableView

Ответы [ 4 ]

1 голос
/ 13 февраля 2020

Пожалуйста, следуйте этим шагам для рабочего решения

* Шаг 1 -> Заменить struct

    struct SectionList : Codable {
        let title : String?
        var items : [RowItems]?
        mutating func filterData(string: String) {
            self.items = self.items?.filter({ (item) -> Bool in
                if item.textField?.contains(string) == true {
                    return true
                }
                return false
            })
        }
    }

    struct Item : Codable {
        let actionType : Int?
        var pickList: [SectionList]?
        let version: Int?
        mutating func filterData(string: String) {
            guard var tempList = pickList else { return }
            for index in 0..<tempList.count {
                tempList[index].filterData(string: string)
            }
            pickList = tempList
        }
    }

* Шаг 2 -> Создать еще один переменная для хранения исходных данных

    var globalAppData: Item?

* Шаг 3 -> Присвоить значение globalAppData при анализе json

    let res = response.items?.filter { $0.actionType == 101}
    AppData = res?.first
    globalAppData = AppData

* Шаг 4 -> Добавить наблюдателя для изменения текста

    searchTxt.addTarget(self, action: #selector(textSearchChange(_:)), for: .editingChanged)

* Шаг 5 -> Заменить метод textDidChange

    @IBAction func textSearchChange(_ sender: UITextField){

        var tempData = globalAppData
        if let text = sender.text, text.isEmpty == false {
        tempData?.filterData(string: text)
        }
        AppData = tempData

        self.tableView.reloadData()
    }

* Дополнительно Шаг 6 ->

Если вы хотите выполнить поиск без учета регистра, замените эту строку

    item.textField?.contains(string)

на

    item.textField?.lowercased().contains(string.lowercased())
1 голос
/ 12 февраля 2020

попробуйте использовать переменную isSearcing bool и массив фильтров

public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool{
   //input text
   let searchText  = textField.text! + string
  //add matching text to arrya
   searchResult = appData.pickerlist.filter({(($0.title as! String).localizedCaseInsensitiveContains(searchText))})

  if(searchArrRes.count == 0){
    isSearching = false
  }else{
    isSearching = true
 }
  self.tableView.reloadData();

  return true
}

, если поиск разрешен, возвращает searchResult в противном случае вы будете использовать основной массив в методах делегата таблицы ... это всего лишь идея и идея ... как вы Вы можете достичь этого .... вы можете искать или добавлять предикат в соответствии с вашими модальными данными

1 голос
/ 13 февраля 2020

// Необходимо применить действие Отправлено. Событие редактируется, изменено

enter image description here

@IBAction func actionTextChange(_ sender: UITextField) {
    print("get text -----\(sender.text)")

}
0 голосов
/ 12 февраля 2020

В методе textSearchChange у вас есть строка запроса sender.text. Вы должны отфильтровать результат и сохранить его в другом массиве. Затем вы можете использовать filteredResultArray в делегате tableView. И каждый раз, когда вы изменяете filteredResultArray, вы должны перезагружать свой tableView.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...