Как использовать поиск для поиска по нескольким полям в Swift? - PullRequest
1 голос
/ 28 сентября 2019

Я пытаюсь получить результаты поиска, чтобы получить данные из: name, dispensaryName, бренда, категории и категории из моего класса ProductList, который извлекает данные из моего Firestore в качестве результатов поиска

Я думаю, что янашел, где найти решение о том, как разрешить поиск работать правильно, чтобы он мог использовать все необходимые поля из моего поиска

проблема в моем расширении SearchbarDelegate внутри функции, я просто не знаю, какизменить его так, чтобы имя, dispensaryName, марка, категория и штамм находились в едином поиске и были представлены в результатах поиска

он не работает должным образом, так как каждый раз, когда я запускаю его, он ищет одно поле илидругое, никогда не все 5 полей одновременно при запуске симулятора

Я проверил код для панели поиска, но он все еще не работает правильно

ПЕРЕМЕННЫЕ

   @IBOutlet weak var searchBar: UISearchBar!
   @IBOutlet weak var productListTableView: UITableView!

   var productInventory: [ProductList] = []
   var productSetup: [ProductList] = []

ОБЗОР

extension ProductListController: UITableViewDelegate, UITableViewDataSource {
        func numberOfSections(in tableView: UITableView) -> Int {
            return 1
        }
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

            if searchBar.text != "" {
                 return self.productInventory.count
            }
            return productSetup.count
        }

         func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            guard let cell =   tableView.dequeueReusableCell(withIdentifier: "ProductListCell") as?
    ProductListCell else { return UITableViewCell() }

            //search not empty
            if searchBar.text != "" {
            cell.configure(withProduct: productInventory[indexPath.row])
        }else{

            cell.configure(withProduct: productSetup[indexPath.row])
        }



        return cell
        }

   }

ДЕЛЕГАТ ПОИСКА

    extension ProductListController : UISearchBarDelegate
    {
       func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
                productInventory = self.productSetup.filter({ (products) -> Bool in
                   return products.name.lowercased().range(of: searchText.lowercased()) != nil
                })
                productInventory = self.productSetup.filter({ (products) -> Bool in
                   return products.dispensaryName.lowercased().range(of: searchText.lowercased()) != nil
                })
                productInventory = self.productSetup.filter({ (products) -> Bool in
                  return products.brand.lowercased().range(of: searchText.lowercased()) != nil
                })
                productInventory = self.productSetup.filter({ (products) -> Bool in
                  return products.category.lowercased().range(of: searchText.lowercased()) != nil
                })
                productInventory = self.productSetup.filter({ (products) -> Bool in
                  return products.strain.lowercased().range(of: searchText.lowercased()) != nil
               })

          self.productListTableView.reloadData()
         }
}

Ответы [ 2 ]

0 голосов
/ 28 сентября 2019

Вы хотите только один фильтр.Просто поместите все условия внутри этого фильтра.

productInventory = self.productSetup.filter({ (products) -> Bool in
   return products.name.lowercased().range(of: searchText.lowercased()) != nil ||
          products.dispensaryName.lowercased().range(of: searchText.lowercased()) != nil ||
          products.brand.lowercased().range(of: searchText.lowercased()) != nil
   // Add the rest as needed.
})

Обратите внимание, что лучше использовать range с соответствующими параметрами.

productInventory = self.productSetup.filter({ (products) -> Bool in
   return products.name.range(of: searchText, options: [ .caseInsensitive, .diacriticInsensitive ]) != nil ||
          products.dispensaryName.range(of: searchText, options: [ .caseInsensitive, .diacriticInsensitive ]) != nil ||
          products.brand.range(of: searchText, options: [ .caseInsensitive, .diacriticInsensitive ]) != nil
   // Add the rest as needed.
})
0 голосов
/ 28 сентября 2019

Ваша проблема в том, что у вас есть пять различных массивов вместо того, что вам нужен отдельный массив типа Dictionary или, возможно, пользовательский Struct / класс.Будет хуже, если вы будете использовать struct / class следующим образом.

class MyData {
    var data1: String!
    var data2: Double!
    var data3: String!
    var data4: String!
    var data5: String! 

    init(data1: String, data2: Double, data3: String, data4: String, data5: String) {
         self.data1 = data1
         self.data2 = data2
         self.data3 = data3
         self.data4 = data4
         self.data5 = data5
    } }

Теперь вместо пяти разных массивов и одного для фильтра создайте два массива типа [MyData], один из которых используется для отображения filterData и использованиячто с методами tableView и фильтруйте его следующим образом.

Создайте объект MyData с помощью метода init it и добавьте его в массив данных, затем отфильтруйте ваш делегат в searchBar следующим образом.

Filter = data.filter {$ 0.data1.localizedCaseInsensitiveContains (searchText)} Приведенный выше фильтр будет искать в массиве данных и возвращать все объекты, в свойстве которых data1 содержит searchText.

Весь ваш код будет выглядеть так:

import UIKit

class TableViewController: UITableViewController, UISearchBarDelegate, UISearchDisplayDelegate {

var data:[MyData] = []

@IBOutlet weak var searchBar: UISearchBar!
var searchActive : Bool = false
var filtered:[MyData] = []


override func viewDidLoad() {
    super.viewDidLoad()


    tableView.delegate = self
    tableView.dataSource = self
    searchBar.delegate = self
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}


override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if(searchActive) {
        return filtered.count
    } else {
        return data.count
    }
}


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

    if(searchActive) {

        cell.label1.text = filtered[indexPath.row].data1
        cell.label2.text = filtered[indexPath.row].data2
        cell.label3.text = filtered[indexPath.row].data3
        cell.label4.text = "\(filtered[indexPath.row].data4) ₺"
        cell.label5.text = filtered[indexPath.row].data5
    } else {

        cell.label1.text = data[indexPath.row].data1
        cell.label2.text = data[indexPath.row].data2
        cell.label3.text = data[indexPath.row].data3
        cell.label4.text = "\(data[indexPath.row].data4) ₺"
        cell.label5.text = data[indexPath.row].data5
    }
    cell.backgroundColor = UIColor.clear
    cell.selectionStyle = UITableViewCellSelectionStyle.none
    return cell
}


func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
    searchActive = true;
}

func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
    searchActive = false;
    self.searchBar.endEditing(true)
}

func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
    searchActive = false;
    self.searchBar.endEditing(true)
}

func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
    searchActive = false;
    self.searchBar.endEditing(true)
}

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

    filtered = data.filter { $0.data1.localizedCaseInsensitiveContains(searchText) }
    if(filtered.count == 0){
        searchActive = false;
    } else {
        searchActive = true;
    }
    self.tableView.reloadData()
}

} Редактировать: вам нужно использовать один массив следующим образом.

for table in result as Any as! NSArray {
    for row in table as! NSArray {
        if let dic = row as? [String : Any] {
            let data1 = dic["data1"] as! String
            let data2 = dic["data2"] as! Double
            let data3 = dic["data3"] as! String
            let data4 = dic["data4"] as! String
            let data5 = dic["data5"] as! String
            let newData =  MyData(data1: data1, data2: data2, data3: data3, data4: data4, data5: data5)
            self.data.append(newData)
        }
    }
}
self.tableView.reloadData()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...