Swift 搜索栏 - 使用 Alamofire 请求更新 table 视图
Swift search bar - updating table view with Alamofire request
我在我的数据库中进行了一些字符串搜索,并且我 return 在用户按下搜索栏上的第 3 个字符后 JSON,之后我将所有结果附加到一个数组并用数据填充表格视图。
虽然我正在处理一个问题。当我搜索 mens
时,我得到的结果显示在 tableview
上
如果我删除所有文本并写女性,一切都很好...但是当我删除一些字符串等时,我在 tableview cellForRowAt 中收到错误 index out of range
。我猜它坏了是因为 tableview 没有时间获取附加数组并填充单元格。
我想知道的是如何让它工作,而不在查询或 reloadData()
中设置时间延迟。我不想要时间延迟的原因是因为某些用户的速度可能很慢 - 旧 iPhone 即使延迟 2 秒,它也可能会崩溃。
这是我的代码
class SearchViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate, UISearchControllerDelegate{
@IBOutlet weak var searchResultTable: UITableView!
let searchController = UISearchController(searchResultsController: nil)
var filteredData = [Products]()
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.isNavigationBarHidden = true
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
definesPresentationContext = true
searchResultTable.tableHeaderView = searchController.searchBar
searchController.searchBar.delegate = self
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchBar.resignFirstResponder()
}
func getSearch(completed: @escaping DownloadComplete, searchString: String) {
if filteredData.isEmpty == false {
filteredData.removeAll()
}
let parameters: Parameters = [
"action" : "search",
"subaction" : "get",
"product_name" : searchString,
"limit" : "0,30"
]
Alamofire.request(baseurl, method: .get, parameters: parameters).responseJSON { (responseData) -> Void in
if((responseData.result.value) != nil) {
let result = responseData.result
if let dict = result.value as? Dictionary<String, AnyObject>{
if let list = dict["product_details"] as? [Dictionary<String, AnyObject>] {
for obj in list {
let manPerfumes = Products(productDict: obj)
self.filteredData.append(manPerfumes)
}
}
}
completed()
}
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView,
heightForRowAt indexPath: IndexPath) -> CGFloat {
return 170
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredData.count
}
func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:iPhoneTableViewCell = tableView.dequeueReusableCell(withIdentifier: "iPhoneTableCell", for: indexPath) as! iPhoneTableViewCell
let prods = self.filteredData[indexPath.row] //HERE I GET THE ERROR
cell.configureCell(products: prods)
return cell
}
}
extension SearchViewController: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
if (searchController.searchBar.text?.characters.count)! >= 3 {
self.getSearch(completed: {
self.searchResultTable.reloadData()
self.searchResultTable.setContentOffset(CGPoint.zero, animated: true)
}, searchString: searchController.searchBar.text!)
} else {
self.searchResultTable.reloadData()
}
}
}
看起来您正在更改 filteredData
的状态,而 tableView 正在更改 reloadData
。例如,如果 numberOfRowsForSection
returns 3,然后用户按下删除键,数组大小将变为 0。这可能是 cellForRow
在请求索引 0,1 或时抛出异常的原因2.
我在我的数据库中进行了一些字符串搜索,并且我 return 在用户按下搜索栏上的第 3 个字符后 JSON,之后我将所有结果附加到一个数组并用数据填充表格视图。
虽然我正在处理一个问题。当我搜索 mens
时,我得到的结果显示在 tableview
如果我删除所有文本并写女性,一切都很好...但是当我删除一些字符串等时,我在 tableview cellForRowAt 中收到错误 index out of range
。我猜它坏了是因为 tableview 没有时间获取附加数组并填充单元格。
我想知道的是如何让它工作,而不在查询或 reloadData()
中设置时间延迟。我不想要时间延迟的原因是因为某些用户的速度可能很慢 - 旧 iPhone 即使延迟 2 秒,它也可能会崩溃。
这是我的代码
class SearchViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate, UISearchControllerDelegate{
@IBOutlet weak var searchResultTable: UITableView!
let searchController = UISearchController(searchResultsController: nil)
var filteredData = [Products]()
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.isNavigationBarHidden = true
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
definesPresentationContext = true
searchResultTable.tableHeaderView = searchController.searchBar
searchController.searchBar.delegate = self
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchBar.resignFirstResponder()
}
func getSearch(completed: @escaping DownloadComplete, searchString: String) {
if filteredData.isEmpty == false {
filteredData.removeAll()
}
let parameters: Parameters = [
"action" : "search",
"subaction" : "get",
"product_name" : searchString,
"limit" : "0,30"
]
Alamofire.request(baseurl, method: .get, parameters: parameters).responseJSON { (responseData) -> Void in
if((responseData.result.value) != nil) {
let result = responseData.result
if let dict = result.value as? Dictionary<String, AnyObject>{
if let list = dict["product_details"] as? [Dictionary<String, AnyObject>] {
for obj in list {
let manPerfumes = Products(productDict: obj)
self.filteredData.append(manPerfumes)
}
}
}
completed()
}
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView,
heightForRowAt indexPath: IndexPath) -> CGFloat {
return 170
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredData.count
}
func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:iPhoneTableViewCell = tableView.dequeueReusableCell(withIdentifier: "iPhoneTableCell", for: indexPath) as! iPhoneTableViewCell
let prods = self.filteredData[indexPath.row] //HERE I GET THE ERROR
cell.configureCell(products: prods)
return cell
}
}
extension SearchViewController: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
if (searchController.searchBar.text?.characters.count)! >= 3 {
self.getSearch(completed: {
self.searchResultTable.reloadData()
self.searchResultTable.setContentOffset(CGPoint.zero, animated: true)
}, searchString: searchController.searchBar.text!)
} else {
self.searchResultTable.reloadData()
}
}
}
看起来您正在更改 filteredData
的状态,而 tableView 正在更改 reloadData
。例如,如果 numberOfRowsForSection
returns 3,然后用户按下删除键,数组大小将变为 0。这可能是 cellForRow
在请求索引 0,1 或时抛出异常的原因2.