【问题标题】:Search through tableview data and handle row selection in Swift在 Swift 中搜索 tableview 数据并处理行选择
【发布时间】:2021-10-04 13:33:07
【问题描述】:

我在从 tableview 搜索数据时遇到问题。我想从 tableview 搜索数据,但在搜索时卡住了。下面是我尝试过的代码。我遇到的问题是无法将类型“[Employee]”的值分配给类型“[String]”请帮忙。 TIA

var empList: [Employee]!
var searchedText = [String]()

 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        
        if searching {
            return searchedText.count
        } else {
            return empList?.count  ?? 0
        }
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomCell
        if searching {
            cell.lblTitle.text = searchedText[indexPath.row]
        }else {

            let resObjects = empList?[indexPath.row]

            cell.lblTitle.text = resObjects?.emp_name

        }
return cell
}


 func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        
        searchedText = empList.filter{$0.emp_name?.contains(searchText)}
        
// The above line gives me error as, cannot assign value of type '[Employee]' to type '[String]'
        
        searching = true
        tableView.reloadData()
    }
    
    func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
        searching = false
        searchBar.text = ""
        tableView.reloadData()
    }

【问题讨论】:

  • var searchedText = [String]() 的目标是什么?你想要的是一个被过滤的员工列表,不是吗?所以应该是var filteredEmployees = [Employee](),然后用那个...

标签: ios swift tableview uisearchbar


【解决方案1】:

正如在 cmets 中已经提到的,强烈建议数据源和过滤后的数组是相同类型

并将两者都声明为非可选的空数组并赋予它们更有意义的名称

var employees = [Employee]()
var filteredEmployees = [Employee]()

那么数据源方法就变得很简单了

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return searching ? filteredEmployees.count : employees.count
}
    
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {           
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomCell
    let employee = searching : filteredEmployees[indexPath.row] : employees[indexPath.row]
    cell.lblTitle.text = employee.emp_name
    return cell
}

而在textDidChange 中你必须考虑到用户可以删除所有字符

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    if searchText.isEmpty {
       searching = false
       filteredEmployees.removeAll()
    } else {
       searching = true
       filteredEmployees = employees.filter{$0.emp_name.range(of: searchText, options: .caseInsensitive) != nil}
    }
    tableView.reloadData()
}

func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
    searchBar.text = ""
}

【讨论】:

  • 感谢这项工作。
【解决方案2】:

替换这个:

searchedText = empList.filter{$0.emp_name?.contains(searchText)}

用这个:

searchedText = empList.filter{ ($0.emp_name?.contains(searchText)) ?? false}.map(\.emp_name) ?? []

解决方案是将Employee 的数组映射到String 的数组,其中值是来自Employee 模型的emp_name

P.S:我正在使用 keyPaths >>> map(.emp_name) 因为它更短。

【讨论】:

  • 在地图之后无法获取 (\.emp_name)。收到以下问题无法将类型“[String?]”的值转换为预期的参数类型“[String]”
  • @RakshitKumar 我已经编辑了我的答案以安全地解开过滤器中的可选字符串。
猜你喜欢
  • 2018-12-10
  • 1970-01-01
  • 1970-01-01
  • 2017-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多