2016-11-21 1 views
0

У меня есть 5 меток, которые получают данные из массива SQL Query, в каждой ячейке на tableView. Я хочу реализовать на нем панель поиска. Строка поиска должна искать через 1 конкретную метку. он работает и фильтрует эту конкретную метку, но когда она фильтруется, другие 4 метки не будут обновляться, и они вообще не меняются. Я не могу понять. Поскольку у меня есть только 1 отфильтрованные данные из строки в строке поиска, я не знаю, как мне фильтровать другие. БлагодаряSwift Search Bar с несколькими данными

EDIT: До сих пор не могу понять о классах и добавления данных и у меня есть ошибка

«Значение типа„[String]“имеет ни один из членов „localizedCaseInsensitiveContains“»

на функции SearchBar

import UIKit 

class TableViewController: UITableViewController, UISearchBarDelegate, UISearchDisplayDelegate { 

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

@IBAction func sqlExecute(_ sender: AnyObject) { 

var client = SQLClient() 
    client.connect("sql_ip", username: "username", password: "password", database: "database") { 
     success in 

     if success { 
      client.execute("sql query") { 
       result in 

       for table in result as Any as! NSArray { 
        for row in table as! NSArray { 
         for column in row as! NSDictionary { 

          if column.key as! String == "data1" { 
           MyData.init(data1: "\(column.value)") 
          } else if column.key as! String == "data2" { 
           MyData.init(data2: column.value as! Double) 
          } else if column.key as! String == "data3" { 
           MyData.init(data3: "\(column.value)") 
          } else if column.key as! String == "data4" { 
           MyData.init(data4: "\(column.value)") 
          } else if column.key as! String == "data5" { 
           MyData.init(data5: "\(column.value)") 
          } 
         } 
        } 
       } 
       client.disconnect() 
       self.tableView.reloadData() 
      } 
     } 
    } 
} 
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])" 
     cell.label2.text = "\(filtered[indexPath.row])" 
     cell.label3.text = "\(filtered[indexPath.row])" 
     cell.label4.text = "\(filtered[indexPath.row])" 
     cell.label5.text = "\(filtered[indexPath.row])" 
    } else { 

    cell.label1.text = "\(data[indexPath.row])" 
    cell.label2.text = "\(data[indexPath.row])" 
    cell.label3.text = "\(data[indexPath.row])" 
    cell.label4.text = "\(data[indexPath.row])" 
    cell.label5.text = "\(data[indexPath.row])" 
    } 
    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() 
} 

Это файл класса:

import Foundation 

class MyData { 
var data1 = [String]() 
var data2 = [Double]() 
var data3 = [String]() 
var data4 = [String]() 
var data5 = [String]() 


init(data1: String) { 
    self.data1.append(data1) 
} 
init(data2: Double) { 
    self.data2.append(data2) 
} 
init(data3: String) { 
    self.data3.append(data3) 
} 
init(data4: String) { 
    self.data4.append(data4) 
} 
init(data5: String) { 
    self.data5.append(data5) 
} 
} 
+1

вы только обновляете ярлык1 из отфильтрованного массива, так что еще 4 текста надписей не изменяются из фильтрованного массива. Вы действительно хотите эту вещь или нет. –

+0

Я хочу обновить их все сразу. Все данные ярлыков поступают из одной и той же строки SQL Query, поэтому на самом деле все метки являются значениями столбцов одной и той же строки – fuzunspm

+0

, но все остальные массивы не изменяются при фильтрации из Data1 и помещаются в фильтрованный массив. –

ответ

1

Ваша проблема у вас есть пять различных массивов вместо того, что вам необходимо иметь единый массив типа Dictionary или, возможно, пользовательские Struct/class. Это тесто, если вы используете 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 
    } 
} 

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

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

filtered = 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() 
    } 
} 

Edit: Вы должны использовать один массив, как таким образом.

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() 
+0

Я преобразовал свой код, как ваш пример, но я не могу добавить результаты запроса в MyData. Он дает ошибку «Значение типа [MyData] не имеет члена данных1» – fuzunspm

+1

@fuzunspm Обновите свой вопрос с помощью нового кода, который вы используете, и покажите, где вы получаете эту ошибку. –

+0

Я обновил вопрос – fuzunspm