Swift 3/4:SearchBar未在TableView

时间:2018-04-20 06:37:37

标签: ios swift tableview uisearchbar nsnotificationcenter

我有一个弹出窗口,顶部是searchBar,下面是TableView。 TableView由动态数据填充。我有一个自定义tableViewCell,带有名称标签和一个复选框( M13CheckBox库)来选择名称。

现在,当我搜索名称时,首先,当用户在搜索栏中键入名称时,不会加载tableView。例如,假设有人名为" Mary "," Mackenzie "," 玛格丽特"和" Mallory "。我想搜索" Margaret ",以便我开始输入" Mar "在searchBar中,然后" Mary "和" 玛格丽特"在tableView中正确过滤,但是当我返回ie" Ma "时,它应显示所有4个名称,因为" Ma "列表中存在,但tableView没有显示任何内容。

因此,如果字母包含在名称中,则tableView应始终作为searchBar中的用户类型重新加载。请帮我解决这个问题。由于它是一个弹出窗口,我通过通知将数据从另一个VC传递给tableView。 这是我的搜索VC代码:

class ParticipantsListVC: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate{

public static var participantNameArray:[String] = [String]()         //global var
var viewController: ViewController!

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.delegate = self
    tableView.dataSource = self
    searchParticipantFilter.delegate = self

    viewController = ViewController()

    let notificationName = NSNotification.Name("reloadList")       
    NotificationCenter.default.addObserver(forName: notificationName, object: nil, queue: OperationQueue.main) { (notifObject) in
        self.tableView.reloadData()
    }
}

func searchBar(_ searchBar: UISearchBar, textDidChange searchText:String) {
    if searchText == "" {
        ParticipantsListVC.participantNameArray.removeAll()
        viewController.getParticipantList()         // func to get list from sever
    }else{           
        ParticipantsListVC.participantNameArray = ParticipantsListVC.participantNameArray.filter({(name) -> Bool in                
            return name.lowercased().contains(searchText.lowercased())
        })            
    }
    self.tableView.reloadData()
  }
}

此外,如果我选择一个名称,则在该名称前面选中checkBox。但是当我点击searchBar中的cancel(X)时,则表示tableView中的第一个单元格被选中,而不是我选择的名称。在从筛选列表中选择名称后,我不知道为什么总是选择第一个单元格。

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

    let dict = ParticipantsListVC.participantNameArray[indexPath.row]
    cell.participantNameLabel.text = dict

    if selectedIndexPaths.contains(indexPath) {
        cell.selectedParticipantCB.setCheckState(.checked, animated: true)
    }else{
        cell.selectedParticipantCB.setCheckState(.unchecked, animated: true)
    }
    return cell
}

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

    // Since any random cell was getting selected on scrolling So I added this code. 
    tableView.deselectRow(at: indexPath, animated: true)           
    if selectedIndexPaths.contains(indexPath) {
        selectedIndexPaths.removeObject(object: indexPath)            
    }else{
        selectedIndexPaths.append(indexPath)
    }
    tableView.reloadData()
}

我不想在headerView或其他tableView中使用searchBar来显示已过滤的列表。非常感谢。谢谢。

2 个答案:

答案 0 :(得分:0)

struct namelist {

    var searchname: NSString

}

var searchActive = Bool()
var newSearchArray = [namelist]()

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
          return searchActive ? newSearchArray.count  : nameOldArray.count

    }

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

        let Cell:SearchTableViewCell! = tableView.dequeueReusableCell(withIdentifier: "Cell") as! SearchTableViewCell
        Cell.selectionStyle = .none

        if (searchActive == true) {

            if ( newSearchArray.count > 0) {

                var para = NSMutableAttributedString()
                para = NSMutableAttributedString(string:(newSearchArray[indexPath.row].searchname) as String)

            do {

                let regex = try NSRegularExpression(pattern: searchText, options: NSRegularExpression.Options.caseInsensitive )
                let nsstr = newSearchArray[indexPath.row].searchname
                text = nsstr as String
                let all = NSRange(location: 0, length: nsstr.length)
                var matches : [String] = [String]()
                regex.enumerateMatches(in: text, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: all) {

                    (result : NSTextCheckingResult?, _, _) in

                    if let r = result {

                        let results = nsstr.substring(with: r.range) as String
                        matches.append(results)
                        let substringrange = result!.rangeAt(0)
                        para.addAttribute(NSForegroundColorAttributeName, value:UIColor.init(red: 237/255.0, green: 60/255.0, blue: 58/255.0, alpha: 1.0), range: substringrange)
                        Cell.namelbl.attributedText = para
                    }
                }

            } catch {

             }

            }
        }
        else {

            Cell.namelbl.text = self.searchname[indexPath.row] as? String
        }
        return Cell

    }

func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {

         searchArray.removeAllObjects()
        newSearchArray.removeAll()

        if Search.text != nil {

            for i in 0 ..< searchname.count {

                searchText = Search.text!
                text = ((searchname.object(at: i))) as! String

                if text.lowercased().contains(searchText.lowercased()) {

                    let elm = namelist(searchname: text as NSString)
                    self.newSearchArray.append(elm)
                }



            }

        }
         searchActive = !newSearchArray.isEmpty
         searchBar.resignFirstResponder()
         yourTableName.reloadData()

    }

答案 1 :(得分:0)

您需要创建另一个数组来保存数据数组的备份。

var arrParticipantList = [String]()
var arrParticipantListBackup = [String]()

override func viewDidLoad() {
    super.viewDidLoad()

    self.searchBar.delegate = self
    self.tblParticipantList.delegate = self
    self.tblParticipantList.dataSource = self
    self.arrParticipantList = ["Mary", "Mackenzie", "Margaret", "Mallory","Molly"]
    self.arrParticipantListBackup = self.arrParticipantList
}

搜索搜索字符串,重新填充数组和重新加载tableview的代码

extension ViewController: UISearchBarDelegate {

    func searchBar(_ searchBar: UISearchBar, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {

        var searchText = searchBar.text! + text
        if range.length > 0 {

            if range.location == 0 {

                self.arrParticipantList = self.arrParticipantListBackup
                self.tblParticipantList.reloadData()
                return true
            }
            searchText = String(searchText.dropLast(range.length))
        }
        self.arrParticipantList = self.arrParticipantListBackup.filter({$0.lowercased().hasPrefix(searchText.lowercased())})
        self.tblParticipantList.reloadData()
        return true
    }

    func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {

        self.searchBar.text = ""
        self.searchBar.resignFirstResponder()
        self.arrParticipantList = self.arrParticipantListBackup
        self.tblParticipantList.reloadData()
    }
}

tableview代码

extension ViewController: UITableViewDelegate, UITableViewDataSource {

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

        return self.arrParticipantList.count
    }

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

        let cell = tableView.dequeueReusableCell(withIdentifier: "cell")
        cell?.textLabel?.text = self.arrParticipantList[indexPath.row]
        return cell!
    }
}

希望这能解决您的问题。