在结构上使用 UISearchbar

Using UISearchbar on Struct

我的项目中有两个 UITableViewControllers。第一个只是一个简单的 tableView,它显示一个普通的 array。第二个 tableViewStruct
填充 我已经在第一个 ViewController 中实现了 UISearcBar,没有任何问题。我遵循 this guide 这是我在第一个 viewController 中用于搜索栏的代码:

let listArray = ["Item1", "Item2", "Item3", "Item4", "Item5"]
var searchData: [String]!        

 override func viewDidLoad() {
        super.viewDidLoad()
        tableView.dataSource = self
        searchBar.delegate = self
        searchData = listArray
    }     

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "TableCell", for: indexPath) as UITableViewCell
        cell.textLabel?.text = searchData[indexPath.row]
        return cell
    }    

  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return filteredData.count
    }

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

        searchData = searchText.isEmpty ? listArray : listArray { (item: String) -> Bool in
            return item.range(of: searchText, options: .caseInsensitive, range: nil, locale: nil) != nil
        }

        tableView.reloadData()
    }

在第二个 ViewController 中,我使用 Struct 来填充 tableView
当我尝试实现 searchBar 时出现错误:

 struct ObjectModel {

        var objectProducer: String?
        var objecType: String?
        var unit: String?
        var contentSize: Double?
        var amount: Double?
        var addedDate: String?

    }    

     var objectList = [ObjectModel]()
        //Search data
      var filteredData = [ObjectModel]()    


        override func viewDidLoad() {
            super.viewDidLoad()
       //SearchData
            searchBar.delegate = self
            filteredData = objectList  //   
          }        

     func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
           return filteredData.count
        }    

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

            //the artist object
                   let object: ObjectModel

                   object = objectList[indexPath.row]

if activeSearch = false {    

              cell.objectNameLabel.text = "\(object.objectProducer ?? "Missing data"), \(object.objecType ?? "Missing data")"    
} else {
            cell.objectNameLabel.text = filteredData[indexPath.row] //Error: Cannot assign value of type 'ObjectModel' to type 'String?'    
}

            return cell

        }   


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

              filteredData = searchText.isEmpty ? objectList : objectList.filter { (item: String) -> Bool in //Error: 'String' is not convertible to 'ObjectModel'
                  return item.range(of: searchText, options: .caseInsensitive, range: nil, locale: nil) != nil
              }

              tableView.reloadData()
          }    

使用Struct时应该如何实现搜索?

你必须改变

cell.objectNameLabel.text = filteredData[indexPath.row] 

   cell.objectNameLabel.text = filteredData[indexPath.row].objectProducer

因为在 ObjectModel 结构中,您必须分配 属性 之一必须分配给 UILabeltext 变量。您可以分配

    var objectProducer: String?
    var objecType: String?
    var unit: String?
    var contentSize: Double?
    var amount: Double?
    var addedDate: String?

属性String描述。例如,如果你想分配金额,你可以使用

cell.objectNameLabel.text = "\(filteredData[indexPath.row].amount!)"

或者有更好的方法。

你必须用 CustomStringConvertible 扩展你的 ObjectModel 这样你的所有结构变量都可以描述为字符串然后它可以像那样工作

cell.objectNameLabel.text = filteredData[indexPath.row] 

你可以像下面这样扩展它。

extension ObjectModel: CustomStringConvertible{

  public var description: String { 
    return "amount \(self.amount) producer \(self.producer) bla bla"
  }

}

// 编辑

用主线程改成它。

tableView.reloadData()

至:

DispatchQueue.main.async { 


   self.tableView.reloadData()

}