清除搜索结果后,Swift Tableview 搜索结果单元格选择复选标记未保存

Posted

技术标签:

【中文标题】清除搜索结果后,Swift Tableview 搜索结果单元格选择复选标记未保存【英文标题】:Swift Tableview search result cell selection checkmark not saving after clearing the search result 【发布时间】:2019-11-13 07:17:24 【问题描述】:

在 myscenario 中,我在 codable 的帮助下将 JSON 数据列出到 Tableview 中。在这里,我有一个 Tableview 和带有过滤器数组的 searchBar。此外,使用checkmark 选项实现了tableview 多个单元格选择。在这里,不搜索选定的单元格复选标记persistant 工作正常,但如果我搜索特定数据并选择单元格,复选标记显示,但清除搜索结果(fileterarray to tableviewarray) 后复选标记未显示(其平均选定的单元格复选标记未保留且未显示清除搜索结果后)。我在代码库中的某个地方犯了错误。请更正并提供一个可靠的解决方案。

实际操作和问题是需要允许用户通过勾选启用和不搜索来选择他们的单元格。没有搜索一切正常,但搜索选定的检查不持久......

JSON 可编码

// MARK: - TeamListRoot
struct TeamListRoot: Codable 
    let status: Bool
    let data: [TeamListData]


// MARK: - TeamListData
struct TeamListData: Codable, Hashable 
    let userid: String?
    let firstname, designation: String?
    let profileimage: String?
    var isSelected = false

    private enum CodingKeys : String, CodingKey 
        case userid, firstname, designation, profileimage
    

我的 Tableview 和 SearchBar 集合

@IBOutlet weak var searchbar: UISearchBar!
@IBOutlet var tableView: UITableView!
var searching = false
var membersData = [TeamListData]()
var filteredData = [TeamListData]()

我的 Tableview 代表

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return searching ? filteredData.count : membersData.count


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
       let cell:TeamlistCustomCell = self.tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as! TeamlistCustomCell
       let textForRow = searching ? filteredData[indexPath.row] : membersData[indexPath.row]
       cell.empName.text = textForRow.firstname
       cell.designationLabel.text = textForRow.designation
       cell.accessoryType = textForRow.isSelected ? .checkmark : .none
       return cell


func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
       self.tableView.deselectRow(at: indexPath, animated: true)
       if  searching == false 
           membersData[indexPath.row].isSelected.toggle()
        else 
           filteredData[indexPath.row].isSelected.toggle()
       
       tableView.reloadRows(at: [indexPath], with: .none)
       let selectedAreas = membersData.filter$0.isSelected

搜索栏代表

func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) 
      self.searchbar.setShowsCancelButton(true, animated: true)
      searching = true


func searchBarTextDidEndEditing(_ searchBar: UISearchBar) 
      self.searchbar.setShowsCancelButton(false, animated: true)
      searching = false


func searchBarSearchButtonClicked(_ searchBar: UISearchBar) 
      searching = false
      self.searchbar.resignFirstResponder()
      self.searchbar.text = ""
      filteredData.removeAll()
      self.tableView.reloadData()


func searchBarCancelButtonClicked(_ searchBar: UISearchBar) 
       searching = false
       self.searchbar.resignFirstResponder()
       self.searchbar.text = ""
       filteredData.removeAll()
       self.tableView.reloadData()


func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) 
       if !searchText.isEmpty 
           filteredData = membersData.filter( ($0.firstname?.localizedCaseInsensitiveContains(searchText))! )
           searching = true
         else 
            filteredData.removeAll()
            searching = false
        
        tableView.reloadData()

【问题讨论】:

@vadian 你能检查一下这个问题吗?请给我一个答案 【参考方案1】:

斯威夫特 5

//替换你的Array声明

var membersData: [TeamListData] = [TeamListData]()
var filteredData: [TeamListData] = [TeamListData]() 

//替换didSelectRowAt代码

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 

    self.tblSearch.deselectRow(at: indexPath, animated: true)

    if  searching == false 

        if let row = self.membersData.firstIndex(where:  $0.userid == membersData[indexPath.row].userid ) 

            membersData[row].isSelected.toggle()
        
     else 

        if let row = self.membersData.firstIndex(where:  $0.userid == filteredData[indexPath.row].userid ) 

           membersData[row].isSelected.toggle()
        

        if let row = self.filteredData.firstIndex(where:  $0.userid == filteredData[indexPath.row].userid ) 

            filteredData[row].isSelected.toggle()
        
    

    tableView.reloadRows(at: [indexPath], with: .none)

【讨论】:

很棒的兄弟。非常感谢。我会在这里尝试更新你。【参考方案2】:

我的解决方案是在 WillDisplay 单元格中重新加载 tableView 后设置选择。

    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) 
    let contact = contactsFiltered[indexPath.row]
    if selectedContacts.contains(contact) 
        tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
     else 
        tableView.deselectRow(at: indexPath, animated: false)
    
    

我只需要让我的联系人过滤保持最新

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
        let contactToAppend = contactsFiltered[indexPath.row]
        selectedContacts.append(contactToAppend)


    func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) 
        if let contactCell = tableView.cellForRow(at: indexPath) as? ContactTVCell 
            if let contactToDelete = contactCell.contact 
                selectedContacts.removeAll(where:  $0 == contactToDelete)
            
        
    

【讨论】:

【参考方案3】:

您正在切换是在您搜索时从过滤数据中选择。 完成后,您从 membersData 加载项目。在 membersData 你没有选择行

改变这个:

 if  searching == false 
           membersData[indexPath.row].isSelected.toggle()
        else 
           filteredData[indexPath.row].isSelected.toggle()
       

到这个:

      membersData[indexPath.row].isSelected.toggle()
       filteredData[indexPath.row].isSelected.toggle()

【讨论】:

非常感谢您的帖子。我在这里有一个疑问,如果假设已经在 membersData 中选择了复选标记,如果用户搜索相同的数据,然后过滤数据再次有机会允许复选标记重复?因为每次选择我都将选定的单元格数据添加到数组中以用于其他过程。此外,我会在每次单击搜索栏取消按钮时清除搜索结果数组。所以我认为上述解决方案还不够:) 我不知道你所说的重复复选标记是什么意思。如果您搜索相同的文本,则必须在搜索结果中检查您之前检查过的 prev Rows。只是尝试调试,我不知道你在做什么 我尝试了上面的代码,但仍然无法正常工作。请您再次检查我的搜索栏代表团,因为我认为我在那里编写了一些错误。 它应该可以工作。我不知道你的代码有什么问题。顺便说一句,为什么在按下搜索按钮时清除过滤后的数据?

以上是关于清除搜索结果后,Swift Tableview 搜索结果单元格选择复选标记未保存的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift4 中取消选中 TableView 所有 TableView 选择

Swift 如何在从 API 接收数据后填充我的 tableView

Swift UISearchController tableview 搜索结果滚动不会在键盘上方移动到最后一行

ios swift在textView单元格中显示/隐藏元素并清除其空间

tableview.reloaddata() 在使用 coredata 时搜索栏取消按钮后不起作用

Swift 远程搜索使 Tableview 崩溃