搜索时tableview错误
Posted
技术标签:
【中文标题】搜索时tableview错误【英文标题】:tableview error while searching 【发布时间】:2016-02-18 11:37:25 【问题描述】:嗨,我有两个数组,只有一个数组正在使用搜索栏进行更新。我保留 TitleArray 以显示在 tableView 标题中,而 detailsArray 显示在 tableView 子标题中。一旦我开始在键入后仅搜索标题但字幕没有任何变化.
@IBOutlet 弱变量 AirportsTableView: UITableView!
var TitleArray = [String]()
var DetailsArray = [String]()
var NumberOfRows = 0
var filteredNamesArray = [String]()
var filteredDetailsArray = [String]()
var resultSearchController = UISearchController!()
**override func viewDidLoad()
super.viewDidLoad()**
// Do any additional setup after loading the view.
self.resultSearchController = UISearchController(searchResultsController: nil)
self.resultSearchController.searchResultsUpdater = self
self.resultSearchController.dimsBackgroundDuringPresentation = false
self.resultSearchController.searchBar.sizeToFit()
self.resultSearchController.loadViewIfNeeded()
self.AirportsTableView.tableHeaderView = self.resultSearchController.searchBar
self.AirportsTableView.reloadData()
parseJSON()
func parseJSON()
if let path = NSBundle.mainBundle().pathForResource("airports", ofType: "json")
do
let data = try NSData(contentsOfURL: NSURL(fileURLWithPath: path), options: NSDataReadingOptions.DataReadingMappedIfSafe)
let jsonObj = JSON(data: data)
if jsonObj != JSON.null
// print("jsonData:\(jsonObj)")
NumberOfRows = jsonObj.count
for i in 0...NumberOfRows
let City = jsonObj[i]["city"].string as String!
let Country = jsonObj[i]["country"].string as String!
let Iata = jsonObj[i]["iata"].string as String!
let Name = jsonObj[i]["name"].string as String!
self.TitleArray.append("\(City) - \(Country) - \(Iata)")
self.DetailsArray.append("\(Name)")
else
print("could not get json from file, make sure that file contains valid json.")
catch let error as NSError
print(error.localizedDescription)
else
print("Invalid filename/path.")
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
*/
// MARK: - Table view data source
func numberOfSectionsInTableView(tableView: UITableView) -> Int
// #warning Incomplete implementation, return the number of sections
return 1
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
// #warning Incomplete implementation, return the number of rows
if self.resultSearchController.active
return self.filteredNamesArray.count
else
return self.TitleArray.count
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell?
if self.resultSearchController.active
cell!.textLabel?.text = self.filteredNamesArray[indexPath.row]
else
cell!.textLabel?.text = self.TitleArray[indexPath.row]
cell!.detailTextLabel?.text = self.DetailsArray[indexPath.row]
return cell!
func updateSearchResultsForSearchController(searchController: UISearchController)
self.filteredNamesArray.removeAll(keepCapacity: false)
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %@", searchController.searchBar.text!)
let array = (self.TitleArray as NSArray).filteredArrayUsingPredicate(searchPredicate)
self.filteredNamesArray = array as! [String]
self.AirportsTableView.reloadData()
// MARK: - Segues
/*
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
if segue.identifier == "AirportDetails"
if let indexPath = self.AirportsTableView.indexPathForSelectedRow
let airportDetail : Airports = TitleArray[indexPath.row]
let controller = (segue.destinationViewController as! UINavigationController).topViewController as! AllWaysFlightsViewController
controller.airportDetail = airportDetail
controller.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem()
controller.navigationItem.leftItemsSupplementBackButton = true
*/
【问题讨论】:
过滤结果中的详细信息文本在哪里 你想不想看到detailTextLabel
您好,详细信息文本已显示在 detailTextLabel 中,但在搜索时不会更新。希望你明白我的意思
看到这个链接它可以帮助你***.com/questions/10317692/…
你提到的链接不适用于 swift 2,这是我第一次从事编码工作:(
【参考方案1】:
不要使用两个单独的数组,而是只使用一个数组并用包含两个变量的对象填充它,您正在使用它来填充 tableView。
class Address
var city: String
var detail: String
init(city: String, detail:String)
self.city = city
self.detail = detail
像这样解析你的 json:
for i in 0...NumberOfRows
let City = jsonObj[i]["city"].string as String!
let Country = jsonObj[i]["country"].string as String!
let Iata = jsonObj[i]["iata"].string as String!
let Name = jsonObj[i]["name"].string as String!
let city = "\(City) - \(Country) - \(Iata)"
let address = Address(city: city, detail: Name)
self.TitleArray.append(address)
self.filteredNamesArray.append(address)
过滤包含地址的标题数组。您的 titlearray 和过滤后的数组第一次都包含相同的数据,您可以参考 json 解析。在这里,您可以使用一个进行过滤,当搜索栏为空时,用户取消他的搜索,您可以从另一个重新填充您的数组。
func updateSearchResultsForSearchController(searchController: UISearchController)
self.filteredNamesArray.removeAll(keepCapacity: false)
let searchPredicate = NSPredicate(format: "SELF.city CONTAINS[c] %@", searchController.searchBar.text!)
let array = (self.TitleArray as NSArray).filteredArrayUsingPredicate(searchPredicate)
self.filteredNamesArray = array as! [Address]
self.AirportsTableView.reloadData()
您的 tableView 逻辑将相应更改
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
// #warning Incomplete implementation, return the number of rows
return self.filteredNamesArray.count
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell?
let address = self.filteredNamesArray[indexPath.row]
cell!.textLabel?.text = address?.city
cell!.detailTextLabel?.text = address?.detail
return cell!
【讨论】:
我应该添加带有地址类的新 swift 文件吗?因为我在 parseJSOn 函数中显示了我的 NS 数据的错误 yes 创建一个新的 swift 文件并添加上面提到的代码。 我做了一些更改,并且在更新搜索结果中只有一个错误:let array = (self.TitleArray as NSArray).filteredArrayUsingPredicate(searchPredicate) 不能将 [Address] 类型的值转换为强制类型 NSArray 像var TitleArray = [Address]()
和 var filteredNamesArray = [Address]()
一样声明您的数组,并更改您的方法 self.filteredNamesArray = array as! [Address]
的行
这里有更好的解决方案(查看解决方案)[***.com/questions/33030171/…【参考方案2】:
您需要更改过滤数据的方式,以便您不仅仅应用您显式迭代并检查谓词的谓词,如果找到匹配项,则将该项目和相应的描述放入过滤后的数组中。
类似:
func updateSearchResultsForSearchController(searchController: UISearchController)
self.filteredNamesArray.removeAll(keepCapacity: false)
self.filteredDetailsArray.removeAll(keepCapacity: false)
let searchString = searchController.searchBar.text!
var index = 0
for title in self.TitleArray
if title.rangeOfString(searchString).location != NSNotFound
self.filteredNamesArray.append(title)
self.filteredDetailsArray.append(self.DetailsArray[index])
index += 1
self.AirportsTableView.reloadData()
【讨论】:
嗨,我放了它并改变了一点点,因为它显示错误但仍然显示(类型'范围,索引。?'的值没有成员'位置'以上是关于搜索时tableview错误的主要内容,如果未能解决你的问题,请参考以下文章
使用 SearchBar 时,复选标记与 TableView 中的错误行相关联
TableView 中的搜索栏:输入搜索文本字符串的最后一个字符时应用程序崩溃