xcode UITableViewCells在UISearchController激活时取消选择自身

pgpifvop  于 2023-01-14  发布在  其他
关注(0)|答案(1)|浏览(110)

我有一个UITableView,其中包含可选中的单元格。这个功能非常好用。不幸的是,当我尝试使用UISearchController筛选特定单元格时,任何选中的单元格都会自动取消选中。此外,如果我搜索一个单元格并从UISearchController筛选的列表中选择它,当我关闭UISearchController时,我选择的单元格不会保持选中状态。总结一下,当UISearchController被激活或关闭时,所有单元格都处于未选中状态。我该如何解决这个问题?我希望能够自由选择项目,搜索项目并选择它们,并且所有选定的项目将始终保持选中状态,除非我有意取消选中它们。

import UIKit
import SPStorkController

struct Part {
    var title: String?
    var location: String?
}

class InspectorViewController: UIViewController, UINavigationControllerDelegate, UITableViewDataSource, UITableViewDelegate, UISearchResultsUpdating {
    
    private let initials = InspectorPartsList.getInitials() // model
    private let parts = InspectorPartsList.getDamageUnrelatedParts() // model
    
    var searchController = UISearchController(searchResultsController: nil)
    var filteredParts: [Part] = []
    var isSearchBarEmpty: Bool {
        return searchController.searchBar.text?.isEmpty ?? true
    }
    var isFiltering: Bool {
        return searchController.isActive && !isSearchBarEmpty
    }
    
    var navBar = UINavigationBar()
    
    let inspectorTableView = UITableView() // tableView
    var darkTheme = Bool()

    override func viewDidLoad() {
        super.viewDidLoad()
        // setup the navigation bar
        setupNavBar()
        
        // add the table view
        setupInspectorTableView()
        
        // add the search bar to the tableView
        setupSearchBar()
    }
    
    func setupNavBar() {
        navBar = UINavigationBar(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: 100))
        view.addSubview(navBar)
        let navItem = UINavigationItem(title: "PARTS")
        let doneItem = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(self.addBtnTapped))
        let cancelItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: nil, action: #selector(self.cancelBtnTapped))
        navItem.rightBarButtonItem = doneItem
        navItem.leftBarButtonItem = cancelItem
        navItem.searchController = searchController
        navBar.setItems([navItem], animated: false)
    }
    
    @objc func cancelBtnTapped() {
        // dismiss the storkView
        SPStorkController.dismissWithConfirmation(controller: self, completion: nil)
    }
    
    @objc func addBtnTapped() {
        print("Done tapped")
        // get all of the selected rows
        if let selectedIndexes = inspectorTableView.indexPathsForSelectedRows {
            // Update the InspectionData model with the selected items... this will allow us to update the InspectionTableView in the other view
            
            // create an empty array for the selected parts
            var selectedParts = [Part]()
            
            // loop through every selected index and append it to the selectedParts array
            for index in selectedIndexes {
                selectedParts.append(parts[index.row])
            }
            
            // update the InspectionData model
            InspectionData.sharedInstance.partsData?.append(contentsOf: selectedParts)
            
            // update the inspectionTableView
            updateInspectionTableView()
            
            // dismiss the storkView
            SPStorkController.dismissWithConfirmation(controller: self, completion: nil)
        } else {
            // dismiss the storkView
            SPStorkController.dismissWithConfirmation(controller: self, completion: nil)
        }
    }
    
    func cancelAddPart() {
        // dismiss the storkView
        SPStorkController.dismissWithConfirmation(controller: self, completion: nil)
    }
    
    private func setupInspectorTableView() {
        // set the data source
        inspectorTableView.dataSource = self
        
        // set the delegate
        inspectorTableView.delegate = self
        
        // add tableview to main view
        view.addSubview(inspectorTableView)
        
        // set constraints for tableview
        inspectorTableView.translatesAutoresizingMaskIntoConstraints = false
//        inspectorTableView.topAnchor.constraint(equalTo: fakeNavBar.bottomAnchor).isActive = true
        inspectorTableView.topAnchor.constraint(equalTo: navBar.bottomAnchor).isActive = true
        inspectorTableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
        inspectorTableView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        inspectorTableView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        
        // allow multiple selection
        inspectorTableView.allowsMultipleSelection = true
        inspectorTableView.allowsMultipleSelectionDuringEditing = true
        
        // register the inspectorCell
        inspectorTableView.register(CheckableTableViewCell.self, forCellReuseIdentifier: "inspectorCell")
    }
    
    func setupSearchBar() {
        // add the bar
        searchController.searchResultsUpdater = self
        searchController.hidesNavigationBarDuringPresentation = false
        searchController.obscuresBackgroundDuringPresentation = false
        searchController.searchBar.placeholder = "Search by part name or location"
        definesPresentationContext = true
        searchController.searchBar.sizeToFit()
        self.inspectorTableView.reloadData()
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if isFiltering {
            return filteredParts.count
        }
        return parts.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let inspectorCell = tableView.dequeueReusableCell(withIdentifier: "inspectorCell", for: indexPath)
        
        var content = inspectorCell.defaultContentConfiguration()
        let part: Part
        if isFiltering {
            part = filteredParts[indexPath.row]
        } else {
            part = parts[indexPath.row]
        }
        content.text = part.title
        content.secondaryText = part.location
        inspectorCell.contentConfiguration = content
        
        return inspectorCell
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("didSelectRowAt: \(indexPath.row)")
    }
    
    func updateSearchResults(for searchController: UISearchController) {
        // filter the results
        let searchBar = searchController.searchBar
        print(searchBar.text!)
        filterContentForSearchText(searchBar.text!)
    }
    
    func filterContentForSearchText(_ searchText: String) {
        filteredParts = parts.filter({ (part : Part) -> Bool in
            return (part.title?.lowercased().contains(searchText.lowercased()))! || (part.location?.lowercased().contains(searchText.lowercased()))!
        })
        self.inspectorTableView.reloadData()
    }
    
    private func updateInspectionTableView() {
        NotificationCenter.default.post(name: NSNotification.Name("updateInspectionTable"), object: nil)
    }

}

// CHECKABLE UITABLEVIEWCELL
class CheckableTableViewCell: UITableViewCell {
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        self.selectionStyle = .none
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }
    
    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        self.accessoryType = selected ? .checkmark : .none
    }
}
mepcadol

mepcadol1#

首先,只需在您的数据模型中创建一个变量,以确保选中了哪个项目。

struct Part {

   var title: String?
   var location: String?
   var selected: Bool? = false

}

var parts = [Parts]()

var filterParts = [Parts]()

var searching = false

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 

 if searching {
      return filterParts.count
 }else {
       return parts.count 
 }

//数据源

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let inspectorCell = tableView.dequeueReusableCell(withIdentifier: "inspectorCell", for: indexPath)
         
       if searching {
          inspectorCell.btnSelected = filterParts[indexPath.row].selected
          content.text = filterParts.title
          content.secondaryText = filterParts.location 
       }else {
           inspectorCell.btnSelected = parts[indexPath.row].selected
           content.text = parts.title
           content.secondaryText = parts.location 
       } 
       return inspectorCell
    }

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

        if searching {
            filterParts[indexPath.row].selected = !filterParts[indexPath.row].selected 
        } else {
            parts[indexPath.row].selected = !parts[indexPath.row].selected 
        } 
    }

extension TableView: UISearchBarDelegate {

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

        filterParts = parts.filter { $0.title.lowercased().prefix(searchText.count) == searchText.lowercased() }
        searching = true
        tableView.reloadData()
    }
    
    func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {

        searching = false
        searchBar.text = ""
        tableView.reloadData()
    }
}

相关问题