搜索时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 中的搜索栏:输入搜索文本字符串的最后一个字符时应用程序崩溃

TableView返回视图时隐藏在搜索栏下的第一个单元格

单击搜索时如何更新tableView的框架并隐藏段控件

在快速键入期间使用搜索栏进行搜索时 TableView 崩溃

加载 tableView 时打开可选值时意外发现 nil