实现搜索功能
Implementing Search Functionality
你好,我在我的应用程序上实现了自动完成搜索。我的 mysql 数据库和应用程序中存储了城市,当用户键入任何字符或单词时,应用程序会从数据库中获取结果并显示出来。现在我遇到了一个小的编程问题,我不知道如何解决。
问题出在我获取城市的同一个数组中,我也获取国家名称和州名称。因为我只对城市而不是州和国家实施了搜索,所以我实际上需要那些基于用户搜索城市显示的行的其他列(州,国家)。我会把代码贴在这里以便更好地理解
class CityTableViewController: UITableViewController, UISearchResultsUpdating {
var dict = NSDictionary()
var filterTableData = [String]()
var resultSearchController = UISearchController()
var newTableData = [String]()
override func viewDidLoad() {
super.viewDidLoad()
self.resultSearchController = ({
let controller = UISearchController(searchResultsController: nil)
controller.searchResultsUpdater = self
controller.dimsBackgroundDuringPresentation = false
controller.searchBar.sizeToFit()
self.tableView.tableHeaderView = controller.searchBar
return controller
})()
self.tableView.reloadData()
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if(self.resultSearchController.active){
return self.filterTableData.count
}else {
return dict.count
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CountryTableViewCell
if(self.resultSearchController.active){
cell.cityNameLabel.text = filterTableData[indexPath.row]
cell.countryNameLabel.text = get the country name
cell.stateNameLabel.text = get stateName
return cell
}else{
cell.cityNameLabel.text = (((self.dict["\(indexPath.row)"] as?NSDictionary)!["City"] as?NSDictionary)!["name"] as?NSString)! as String
return cell
}
}
func updateSearchResultsForSearchController(searchController: UISearchController) {
filterTableData.removeAll(keepCapacity: false)
let searchWord = searchController.searchBar.text!
getCityNamesFromServer(searchWord)
let searchPredict = NSPredicate(format: "SELF CONTAINS[c] %@", searchController.searchBar.text!)
print("searchPredict is \(searchController.searchBar.text!)")
for var i = 0; i < self.dict.count; i++ {
let cityName = (((self.dict["\(i)"] as?NSDictionary)!["City"] as?NSDictionary)!["name"] as?NSString)! as String
let countryName = (((self.dict["\(i)"] as?NSDictionary)!["Country"] as?NSDictionary)!["name"] as?NSString)! as String
let stateName = (((self.dict["\(i)"] as?NSDictionary)!["State"] as?NSDictionary)!["name"] as?NSString)! as String
newTableData.append(cityname)
}
let array = (newTableData as NSArray).filteredArrayUsingPredicate(searchPredict)
print("array is\(array)")
filterTableData = array as! [String]
self.tableView.reloadData()
}
func getCityNamesFromServer(searchWord:String){
let url:String = "http://localhost/"
let params = ["city":searchWord]
ServerRequest.postToServer(url, params: params) { result, error in
if let result = result {
print(result)
self.dict = result
}
}
}
}
如果我尝试设置新的州和国家/地区数组,则数据不会正确显示。不属于自己州的城市出现。那么我如何才能正确地保持订单。
数组:
dict
0 = {
City = {
code = 10430;
"country_id" = 244;
id = 8932;
name = Laudium;
"state_id" = 4381;
"updated_at" = "<null>";
};
Country = {
id = 244;
name = "South Africa";
};
State = {
"country_id" = 244;
id = 4381;
name = Gauteng;
};
}; etc
newTableData
["Lynnwood", "Lyndhurst", "Laudium"]
等等
filterTableData
["Laudium", "La Lucia", "Lansdowne"] etc
您应该在字典中搜索匹配项并将匹配的键存储在数组中并在结果中引用这些键。
func updateSearchResultsForSearchController(searchController: UISearchController) {
let searchWord = searchController.searchBar.text!
getCityNamesFromServer(searchWord)
self.filteredKeys.removeAll()
for (key, value) in self.dict {
let valueContainsSearchWord: Bool = (((value as? NSDictionary)?["City"] as? NSDictionary)?["name"] as? String)?.uppercaseString.containsString(searchWord.uppercaseString) ?? false
if valueContainsSearchWord {
self.filteredKeys.append(key as! String)
}
}
self.tableView.reloadData()
}
用这个过滤后的键填充表视图:
让 key = self.filteredKeys[indexPath.row]
let dictionary = self.dict[key] as! NSDictionary
cell.cityNameLabel.text = ((dictionary["City"] as? NSDictionary)!["name"] as? NSString)! as String
cell.countryNameLabel.text = ((dictionary["Country"] as? NSDictionary)!["name"] as? NSString)! as String
cell.stateNameLabel.text = ((dictionary["State"] as? NSDictionary)!["name"] as? NSString)! as String
return cell
只需保存这个过滤后的字典 (self.filteredDictionary) 并使用它来填充 tableView。
我认为另一个问题是,当您从 updateSearchResultsForSearchController:
调用服务器的搜索方法 (getCityNamesFromServer:
) 时,服务器的响应是异步的,之后的过程使用旧的字典数据,因为处理的时候新的还没有准备好。
您应该尝试使用这样的块完成修改 getCityNamesFromServer:
方法:
func updateSearchResultsForSearchController(searchController: UISearchController) {
// Get search word
getCityNamesFromServer(searchWord) { () -> Void in
// Rest of the code comes here
}
}
func getCityNamesFromServer(searchWord:String, completionHandler: (() -> Void) ) {
let url:String = "http://localhost/"
let params = ["city":searchWord]
ServerRequest.postToServer(url, params: params) { result, error in
if let result = result {
print(result)
self.dict = result
}
completionHandler()
}
}
你好,我在我的应用程序上实现了自动完成搜索。我的 mysql 数据库和应用程序中存储了城市,当用户键入任何字符或单词时,应用程序会从数据库中获取结果并显示出来。现在我遇到了一个小的编程问题,我不知道如何解决。
问题出在我获取城市的同一个数组中,我也获取国家名称和州名称。因为我只对城市而不是州和国家实施了搜索,所以我实际上需要那些基于用户搜索城市显示的行的其他列(州,国家)。我会把代码贴在这里以便更好地理解
class CityTableViewController: UITableViewController, UISearchResultsUpdating {
var dict = NSDictionary()
var filterTableData = [String]()
var resultSearchController = UISearchController()
var newTableData = [String]()
override func viewDidLoad() {
super.viewDidLoad()
self.resultSearchController = ({
let controller = UISearchController(searchResultsController: nil)
controller.searchResultsUpdater = self
controller.dimsBackgroundDuringPresentation = false
controller.searchBar.sizeToFit()
self.tableView.tableHeaderView = controller.searchBar
return controller
})()
self.tableView.reloadData()
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if(self.resultSearchController.active){
return self.filterTableData.count
}else {
return dict.count
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CountryTableViewCell
if(self.resultSearchController.active){
cell.cityNameLabel.text = filterTableData[indexPath.row]
cell.countryNameLabel.text = get the country name
cell.stateNameLabel.text = get stateName
return cell
}else{
cell.cityNameLabel.text = (((self.dict["\(indexPath.row)"] as?NSDictionary)!["City"] as?NSDictionary)!["name"] as?NSString)! as String
return cell
}
}
func updateSearchResultsForSearchController(searchController: UISearchController) {
filterTableData.removeAll(keepCapacity: false)
let searchWord = searchController.searchBar.text!
getCityNamesFromServer(searchWord)
let searchPredict = NSPredicate(format: "SELF CONTAINS[c] %@", searchController.searchBar.text!)
print("searchPredict is \(searchController.searchBar.text!)")
for var i = 0; i < self.dict.count; i++ {
let cityName = (((self.dict["\(i)"] as?NSDictionary)!["City"] as?NSDictionary)!["name"] as?NSString)! as String
let countryName = (((self.dict["\(i)"] as?NSDictionary)!["Country"] as?NSDictionary)!["name"] as?NSString)! as String
let stateName = (((self.dict["\(i)"] as?NSDictionary)!["State"] as?NSDictionary)!["name"] as?NSString)! as String
newTableData.append(cityname)
}
let array = (newTableData as NSArray).filteredArrayUsingPredicate(searchPredict)
print("array is\(array)")
filterTableData = array as! [String]
self.tableView.reloadData()
}
func getCityNamesFromServer(searchWord:String){
let url:String = "http://localhost/"
let params = ["city":searchWord]
ServerRequest.postToServer(url, params: params) { result, error in
if let result = result {
print(result)
self.dict = result
}
}
}
}
如果我尝试设置新的州和国家/地区数组,则数据不会正确显示。不属于自己州的城市出现。那么我如何才能正确地保持订单。
数组:
dict
0 = {
City = {
code = 10430;
"country_id" = 244;
id = 8932;
name = Laudium;
"state_id" = 4381;
"updated_at" = "<null>";
};
Country = {
id = 244;
name = "South Africa";
};
State = {
"country_id" = 244;
id = 4381;
name = Gauteng;
};
}; etc
newTableData
["Lynnwood", "Lyndhurst", "Laudium"]
等等
filterTableData
["Laudium", "La Lucia", "Lansdowne"] etc
您应该在字典中搜索匹配项并将匹配的键存储在数组中并在结果中引用这些键。
func updateSearchResultsForSearchController(searchController: UISearchController) {
let searchWord = searchController.searchBar.text!
getCityNamesFromServer(searchWord)
self.filteredKeys.removeAll()
for (key, value) in self.dict {
let valueContainsSearchWord: Bool = (((value as? NSDictionary)?["City"] as? NSDictionary)?["name"] as? String)?.uppercaseString.containsString(searchWord.uppercaseString) ?? false
if valueContainsSearchWord {
self.filteredKeys.append(key as! String)
}
}
self.tableView.reloadData()
}
用这个过滤后的键填充表视图: 让 key = self.filteredKeys[indexPath.row]
let dictionary = self.dict[key] as! NSDictionary
cell.cityNameLabel.text = ((dictionary["City"] as? NSDictionary)!["name"] as? NSString)! as String
cell.countryNameLabel.text = ((dictionary["Country"] as? NSDictionary)!["name"] as? NSString)! as String
cell.stateNameLabel.text = ((dictionary["State"] as? NSDictionary)!["name"] as? NSString)! as String
return cell
只需保存这个过滤后的字典 (self.filteredDictionary) 并使用它来填充 tableView。
我认为另一个问题是,当您从 updateSearchResultsForSearchController:
调用服务器的搜索方法 (getCityNamesFromServer:
) 时,服务器的响应是异步的,之后的过程使用旧的字典数据,因为处理的时候新的还没有准备好。
您应该尝试使用这样的块完成修改 getCityNamesFromServer:
方法:
func updateSearchResultsForSearchController(searchController: UISearchController) {
// Get search word
getCityNamesFromServer(searchWord) { () -> Void in
// Rest of the code comes here
}
}
func getCityNamesFromServer(searchWord:String, completionHandler: (() -> Void) ) {
let url:String = "http://localhost/"
let params = ["city":searchWord]
ServerRequest.postToServer(url, params: params) { result, error in
if let result = result {
print(result)
self.dict = result
}
completionHandler()
}
}