UISearchbar 在 swift 4 中使用 UItextfield
UISearchbar using UItextfield in swift 4
我正在研究 JSON。我的 Json 数据打印到表格视图中。我想用搜索栏过滤该数据。所以我把 Textfield 用于使用 Searchbar。我使用这个网站的参考
我的搜索栏可以使用,但不正常。我想在 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 像下面这样
- 创建项目
- 创建添加文本字段,tableView 连接到 viewcontroller
添加以下代码..
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 来在故事板中创建此动作=]
我正在研究 JSON。我的 Json 数据打印到表格视图中。我想用搜索栏过滤该数据。所以我把 Textfield 用于使用 Searchbar。我使用这个网站的参考
我的搜索栏可以使用,但不正常。我想在 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 像下面这样
- 创建项目
- 创建添加文本字段,tableView 连接到 viewcontroller
添加以下代码..
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 来在故事板中创建此动作=]