如何在搜索后打勾

How to put a checkmark after search

我想在搜索后打勾。我在这里看到了一些答案,但它对我不起作用。我尝试了一些答案,但它只会出错。

这是我写的代码。

struct finalCheckednames { var name: String; var checkMark: Bool}

class ShowBroadcastNamesViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate {

var nameslist = ["Mark","Chris", "James", "Sandra"]
var myIndex = 0
var nameArray = String()
var filteredData = [String]()
var isSearching = false
var selectedNamesToBroadcast = [String]()
var selectedNamesIndex:Int? = nil
var checkmarks = [Int : Bool]()
var hasChecked = Bool()

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as? broadcastNamesTableViewCell {

        let text: String!

        if isSearching {
            text = filteredData[indexPath.row]

        } else {
            text = nameslist[indexPath.row]
        }

        cell.configureCell(text: text)

        if checkmarks[indexPath.row] != nil {
            cell.accessoryType = checkmarks[indexPath.row]! ? .checkmark : .none
        } else {
            checkmarks[indexPath.row] = false
            cell.accessoryType = .none
        }

        return cell

    } else {

        return UITableViewCell()
    }
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  if isSearching {
            selectedNamesIndex = filteredData[indexPath.row] // im also getting an error here

        } else {

    selectedNamesIndex = indexPath.row
    let cell = tableView.cellForRow(at: indexPath)

    if let index = selectedNamesIndex {
        if (cell?.accessoryType == .checkmark) {
            cell!.accessoryType = .none
            checkmarks[indexPath.row] = false
            hasChecked = false

            let indexPathTapped = tableView.indexPath(for: cell!)
            let name = nameslist[(indexPathTapped!.row)]
            print(name, hasChecked)
            if let index = selectedNamesToBroadcast.index(of: name) {
                selectedNamesToBroadcast.remove(at: index)
            }

        } else {
            cell!.accessoryType = .checkmark
            checkmarks[indexPath.row] = true
            hasChecked = true

            let indexPathTapped = tableView.indexPath(for: cell!)
            let name = nameslist[(indexPathTapped!.row)]
            print(name, hasChecked)
            selectedNamesToBroadcast.append(name)

            let selectedNamesToBroadcast = name

            finalCheckednames(name: name, checkMark: hasChecked)
            print(finalCheckednames.self, "XXXX")
        }
    }

}

 func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    if searchBar.text == nil || searchBar.text == "" {
        isSearching = false
        view.endEditing(true)
        tableView.reloadData()
    } else {
        isSearching = true
        filteredData = namelist.filter{[=10=].range(of: searchText, options: .caseInsensitive) != nil}
        tableView.reloadData()

我希望在搜索后留下复选标记。所以至少我可以将所有选中的项目保存在某个地方。

你的代码非常非常非常复杂。完成您的请求的最有效方法是使用结构中的 isChecked 信息,没有别的,没有额外的数组、字典、属性。

为结构和 Bool 取一个更有意义的名称。

struct Person {
    let name: String
    var isChecked: Bool
}

在控制器中命名数据源数组 people 和过滤器数组 filteredPeople。此外,您只需要 isSearching,删除所有其他属性

class ShowBroadcastNamesViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate {

    var people = [Person(name: "Mark", isChecked: false),
                  Person(name: "Chris", isChecked: false),
                  Person(name: "James", isChecked: false),
                  Person(name: "Sandra", isChecked: false)]

    var filteredPeople = [Person]()
    var isSearching = false

var myIndex = 0
var nameArray = String()
var filteredData = [String]()
var selectedNamesToBroadcast = [String]()
var selectedNamesIndex:Int? = nil
var checkmarks = [Int : Bool]()
var hasChecked = Bool()

cellForRow 中强制打开自定义单元格并将其命名为大写(良好做法)。将 name 传递给 configureCell 并根据 isChecked

的值设置附件视图
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! BroadcastNamesTableViewCell

    let person = isSearching ? filteredPeople[indexPath.row] : people[indexPath.row]
    cell.configureCell(text: person.name)
    cell.accessoryType = person.isChecked ? .checkmark : .none
    return cell
}

didSelectRow 中切换 isChecked(并在必要时更新 people 数组)并重新加载行,仅此而已

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    if isSearching {
        filteredPeople[indexPath.row].isChecked.toggle()
        let index = people.firstIndex{[=14=].name == filteredPeople[indexPath.row].name}!
        people[index].isChecked.toggle() 
    } else {
        people[indexPath.row].isChecked.toggle()
    }
    tableView.reloadRows(at: [indexPath], with: .automatic)
}

textDidChange中搜索名字

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    if searchText.isEmpty {
        isSearching = false
        filteredPeople.removeAll()
        view.endEditing(true)
    } else {
        isSearching = true
        filteredPeople = people.filter{[=15=].name.range(of: searchText, options: .caseInsensitive) != nil}
    }
    tableView.reloadData()
 }

中我已经推荐了一个更高效的版本textDidChange,请考虑遵循这些建议。

要让选中的人写

let checkedPeople = people.filter{[=16=].isChecked}