UISearchbar 在 Swift 4 中使用 UItextfield
Posted
技术标签:
【中文标题】UISearchbar 在 Swift 4 中使用 UItextfield【英文标题】:UISearchbar using UItextfield in swift 4 【发布时间】:2018-11-01 11:33:33 【问题描述】:我正在处理 JSON。我的 Json 数据打印到 tableview 中。我想用搜索栏过滤这些数据。所以我把 Textfield 用于使用 Searchbar。我使用本网站的参考资料
http://findnerd.com/list/view/How-to-create-your-own-search-bar-in-Swift-Not-using-UISearchBar/20577/
我的搜索栏可以正常工作,但不能正常工作。我想在搜索栏中写 3 个单词后过滤数据。如果我写“Ku”,那么我的表格视图仍然隐藏。如果我在搜索栏中写“kus”,则搜索栏开始搜索并在表格视图中显示从“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
【问题讨论】:
【参考方案1】:试试这个:
@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
【讨论】:
三字tableview正常工作后没有显示过滤数据> 需要将过滤后的数据设置为tableView dataSource,而不是原来的tableData 你的鲸鱼 :) 先生,我根据您的代码编辑了我的代码,还做了一些更改。我将我的 json 数据放入结构中并显示在 tableview 中。现在我得到过滤的数据,但如何显示到 tableview 是问题。请帮帮我。 您使用patientDetails
作为tableView数据源,它非常简单,您需要将表格视图的数据源设置为您想要显示的内容,因为在这种情况下您正在过滤,您应该将 tableView 数据源设置为结构的过滤版本【参考方案2】:
在 Swift 4 或 Swift 5 中,您可以像下面这样使用.. 你的表视图如下
-
创建项目
创建添加文本字段,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((($0["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 链接下载完整源代码:https://github.com/enamul95/TableView_Search
【讨论】:
参考您的帖子答案,如果可能的话,我可以问一个与 tableView 搜索相关的问题吗?【参考方案3】:您可以在过滤之前检查文本的大小:
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
【讨论】:
我已经尝试过了,但是没有用。编辑此代码后,当我在搜索栏中编写第一个单词时,它显示所有未过滤的数据,并且在我编写第二个单词后,tableview 隐藏和搜索栏不起作用。 为什么不使用导航栏的UISearchBar
?
我用 UISearchBar 完成了这个。但是现在写我的任务是用 UITextfield 做这些事情。【参考方案4】:
请使用此代码:-
func getSearchArrayContains(_ text : String)
tableFilterData = tableData.filter($0.lowercased().contains(text))
isSearch = true
tableview.reloadData()
如果三个字符使用这个链接enter link description here:-
谢谢
【讨论】:
【参考方案5】:以上所有答案都试图通过将更改连接到前一个字符串来对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
来在情节提要中创建此操作
【讨论】:
以上是关于UISearchbar 在 Swift 4 中使用 UItextfield的主要内容,如果未能解决你的问题,请参考以下文章
UISearchBar在Swift中完成后如何停止UIActivityIndicator
如何在 Swift 中使用 UISearchBar 和 NSFetchedResultsController 在 Core Data 上一次获取多个实体?
Swift iOS 8+ UISearchBar图标,占位符和文本居中