UISearchbar 在 swift 4 中使用 UItextfield

UISearchbar using UItextfield in swift 4

我正在研究 JSON。我的 Json 数据打印到表格视图中。我想用搜索栏过滤该数据。所以我把 Textfield 用于使用 Searchbar。我使用这个网站的参考

http://findnerd.com/list/view/How-to-create-your-own-search-bar-in-Swift-Not-using-UISearchBar/20577/

我的搜索栏可以使用,但不正常。我想在 searchbar.If 中写 3 个单词后过滤数据 我写 "Ku" 然后我的 tableview 保持隐藏。如果我在 searchbar 中写 "kus",然后 searchbar 开始搜索并在 tableview 中显示从 "kus" 开始的过滤数据。我的搜索栏相关代码是这些

struct PatientData:Decodable {
var ID : String
var dt_bod : String
var e_gender : String
var int_glcode : String
var var_email : String
var var_fname : String
var var_phoneno : String
var var_uname : String

init(userdata : [String:Any]) {
    self.ID = userdata["ID"] as! String
    self.dt_bod = userdata["dt_bod"] as! String
    self.e_gender = userdata["e_gender"] as! String
    self.int_glcode = userdata["int_glcode"] as! String
    self.var_email = userdata["var_email"] as! String
    self.var_fname = userdata["var_fname"] as! String
    self.var_phoneno = userdata["var_phoneno"] as! String
    self.var_uname = userdata["var_uname"] as! String

} 

var tabledata = [String]()
var tableFilterData = [String]()
var patientDetails = [PatientData]()

@IBAction func textfieldchanged(_ sender: Any) {
    tableview.isHidden = true
}

我的文本字段更改字符功能

public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool{

    let searchText  = textField.text! + string
    if searchText.count >= 3 {
        tableview.isHidden = false

        tableFilterData = tabledata.filter({ (result) -> Bool in
            return result.range(of: searchText, options: .caseInsensitive) != nil
        })

        print(tableFilterData)   // I got filtered data here but how to show this data into the tableview
        tableview.reloadData()
    }
    else{
        tableFilterData = []
    }
    return true
}

tableview 部分是

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

        return patientDetails.count
     }

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

    let aa = patientDetails[indexPath.row].var_fname + " , " + patientDetails[indexPath.row].dt_bod + " , " + patientDetails[indexPath.row].var_phoneno

    self.tabledata.append(aa)

        cell.textLabel?.text = aa
        cell.textLabel?.font = searchTextfield.font

    return cell
}

您可以在过滤器之前检查文本的大小:

public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool{

    var searchText  = textField.text! + string

    if string  == "" {
        searchText = (searchText as String).substring(to: searchText.index(before: searchText.endIndex))
    }
    if searchText == "" {
        isSearch = false
        tableview.reloadData()
    }
    else{
        if searchText.count > 2 {
           getSearchArrayContains(searchText)
        }  
    }
    return true
}

请使用此代码:-

func getSearchArrayContains(_ text : String) {

    tableFilterData = tableData.filter({[=10=].lowercased().contains(text)})
    isSearch = true
     tableview.reloadData()
}

三个字符应该使用这个link:-

谢谢

试试这个:

@objc func textFieldActive() {
    tableView.isHidden = tableFilterData.count > 0 ? false : true
}

public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool{

    let searchText  = textField.text! + string

    if searchText.count >= 3 {
        tableView.isHidden = false

        tableFilterData = tabledata.filter({ (result) -> Bool in
            return result.range(of: searchText, options: .caseInsensitive) != nil
        })

        tableView.reloadData()
    }
    else{
        tableFilterData = []
    }

    return true
}

func tableView(_ tableView: UITableView, numberOfRowsInSection 
section: Int) -> Int {
    return tableFilterData.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let data = tableFilterData[indexPath.row]

    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

    cell.textLabel?.text = data

    return cell
}

在Swift 4或Swift 5中,你可以像下面这样使用.. 你的 tableview 像下面这样

  1. 创建项目
  2. 创建添加文本字段,tableView 连接到 viewcontroller
  3. 添加以下代码..

     class ViewController: UIViewController ,UITableViewDelegate,UITableViewDataSource,UITextFieldDelegate{
    
      @IBOutlet weak var tableView: UITableView!
      @IBOutlet weak var txtName: UITextField!
    
      var originalArr = [[String:Any]]();
      var searchArrRes = [[String:Any]]()
      var searching:Bool = false
    
     override func viewDidLoad() {
        super.viewDidLoad()
    
        //Assign delegate  don't forget
        txtName.delegate = self
        tableView.delegate = self
        tableView.dataSource = self
    
       //my array
      originalArr =   [
        ["name": "abdul", "number": "+8800000001"],
        ["name": "abdin", "number": "+8800000002"],
        ["name": "Enamul", "number": "+8800000003"],
        ["name": "enam", "number": "+8800000004"],
        ["name": "Rafi", "number": "+8800000005"],
        ["name": "Ehaque", "number": "+8800000006"],
        ["name": "ab", "number": "+8800000007"],
        ["name": "Emon", "number": "+8800000008"],
        ["name": "enamu1", "number": "+8800000009"],
        ["name": "rafi", "number": "+88000000010"],
        ["name": "karim", "number": "+88000000011"],
        ["name": "radev", "number": "+88000000012"],
        ["name": "da", "number": "+88000000013"],
        ["name": "aa", "number": "+88000000014"],
        ["name": "rafi", "number": "+88000000010"],
        ["name": "karim", "number": "+88000000011"],
        ["name": "radev", "number": "+88000000012"],
        ["name": "da", "number": "+88000000013"],
        ["name": "aa", "number": "+88000000014"]
       ]
    
    }
    
    
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
       textField.resignFirstResponder()
       return true
    }
    
     public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool{
       //input text
       let searchText  = textField.text! + string
      //add matching text to arrya
       searchArrRes = self.originalArr.filter({(([=10=]["name"] as! String).localizedCaseInsensitiveContains(searchText))})
    
      if(searchArrRes.count == 0){
        searching = false
      }else{
        searching = true
     }
      self.tableView.reloadData();
    
      return true
    }
    
    
      func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
       //check search text & original text
       if( searching == true){
          return searchArrRes.count
       }else{
          return originalArr.count
       }
     }
    
      func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
      //custom cell Custom_cell
      let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! Custom_cell
      //check search text & original text
       if( searching == true){
        var dict = searchArrRes[indexPath.row]
        cell.label_name.text = dict["name"] as? String
        cell.label_number.text = dict["number"] as? String
      }else{
        var dict = originalArr[indexPath.row]
        cell.label_name.text = dict["name"] as? String
        cell.label_number.text = dict["number"] as? String
    
     }
    
      return cell
    }
    
    
    }
    

您可以从 GitHub Link 下载完整源代码:https://github.com/enamul95/TableView_Search

以上所有答案都试图通过将更改连接到前一个字符串来对 UITextField 字符串进行逆向工程。这需要完成,因为在对 UITextField 字符串进行更改之前调用委托方法 shouldChangeCharactersIn

这些实现是错误的,当用户向左滚动光标并继续输入或选择并替换文本时这些实现不起作用(因为答案忽略了 NSRange 委托变量)。

更好的实现是完全不使用委托方法,而是将目标添加到 UITextField。这是有效的,因为 UITextField 继承自 UIControl.

override func viewDidLoad() {
    super.viewDidLoad()
    searchTextField.addTarget(self, action: #selector(searchTextChanged(_:)), for: .editingChanged)
}

@objc func searchTextChanged(_ sender: UITextField) {
    let search = sender.text ?? ""
    filterContentForSearchText(search)
}

func filterContentForSearchText(_ searchText: String) {
    print("Filterin with:", searchText)
    filtered.removeAll()
    filtered = original.filter { thing in
        return "\(thing.value.lowercased())".contains(searchText.lowercased())
    }
    tableView.reloadData()
}

注意:也可以通过创建 @IBAction 并将 Editing Changed 连接从 UITextField 拖到 @IBAction[=22 来在故事板中创建此动作=]