swift - 搜索 Controller - 将 NSPredicate 与模型一起使用时出现问题

标签 swift nspredicate uisearchcontroller

我有一个 TableView ,它从我的服务器获取 json 数据。 现在我想使用 SearchContoller 添加一个搜索栏。单元格(自定义)在搜索前正确显示:

enter image description here

但是当我开始输入时什么也没有显示。这是代码:

型号

import Foundation
class PreviousLocations:NSObject{

 let locationId: String?
 let locationName: String?
 let locationCity:String?
 let locationCountry:String?
 let locationLatitude:String?
 let locationLongitude:String?
 let sport:String?


  init(dictionary:NSDictionary) {
    locationId = dictionary["locationId"]    as? String
    locationName = dictionary["locationName"]    as? String
    locationCity = dictionary["locationCity"]    as? String
    locationCountry = dictionary["locationCountry"]    as? String
    sport = dictionary["sport"]    as? String
    locationLatitude = dictionary["locationLatitude"]    as? String
    locationLongitude = dictionary["locationLongitude"]    as? String

   }
}

然后在 PreviousLocationsViewControllors

 var previousLocation = [PreviousLocations]()
 var filteredPreviousLocations  = [PreviousLocations]()

 fun tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {  
          if section == 0 {     
              return 1
          }

          if section == 1{

              if (self.searchController.active) {
                 return filteredPreviousLocations.count     
              }else{

                 return previousLocation.count
              }

        }
        return 1
    }


func numberOfSectionsInTableView(tableView: UITableView) -> Int {

    return 2
 }

  func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{

       if indexPath.section == 0{

        let addLocationCell = self.tableView.dequeueReusableCellWithIdentifier("addLocationCell", forIndexPath: indexPath) 

        addLocationCell.textLabel?.text = "Add Location"
        return addLocationCell

    }else{

    var locCells:PreviousLocationsTableCell
    let locations : PreviousLocations

        if (self.searchController.active) {

        locCells =  self.tableView.dequeueReusableCellWithIdentifier("previousLocationCell") as! PreviousLocationsTableCell

            locations = filteredPreviousLocations[indexPath.row]
            locCells.useLocations(locations)

         }else{

           locCells = self.tableView.dequeueReusableCellWithIdentifier("previousLocationCell", forIndexPath: indexPath) as! PreviousLocationsTableCell


            locations = previousLocation[indexPath.row]
            locCells.useLocations(locations)

    }

    return locCells
    }
}


//MARK: - Search


func updateSearchResultsForSearchController(searchController: UISearchController)
{

    filteredPreviousLocations.removeAll(keepCapacity: false)
    let searchPredicate = NSPredicate(format: "SELF.locationName == %@", searchController.searchBar.text!)
    let array  = (previousLocation as NSArray).filteredArrayUsingPredicate(searchPredicate)
    print(array)
    filteredPreviousLocations = array as! Array
    self.tableView.reloadData()
}

和自定义单元格

import UIKit
import QuartzCore


class PreviousLocationsTableCell: UITableViewCell {


@IBOutlet weak var conteningView: UIView!
@IBOutlet weak var locatioNameLabel: UILabel!
@IBOutlet weak var locationCityLabel: UILabel!
@IBOutlet weak var sportImage: UIImageView!


func useLocations(location:PreviousLocations) {



    conteningView.layer.masksToBounds = true
    conteningView.exclusiveTouch = false
    // Fill in the data
    locatioNameLabel.text = location.locationName
    locationCityLabel.text = location.locationCity

    let imageSport = UIImage(named: "\(location.sport!).png")
    sportImage.image = imageSport

    func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }


 }

  }

如果我尝试改变这个

    `filteredPreviousLocations = array as! Array`

进入这个

    `filteredPreviousLocations = array as! [String]`

正如在 This 中解释的那样教程,我得到错误 无法将“[String]”类型的值分配给“[PreviousLocations]”类型的值

最佳答案

属性的类型在 [PreviousLocations] 中明确定义,因此您无需转换类型,除非在过滤器行中。格式字符串应该是 locationName == %@

func updateSearchResultsForSearchController(searchController: UISearchController)
{
  let searchPredicate = NSPredicate(format: "locationName == %@", searchController.searchBar.text!)
  filteredPreviousLocations = (previousLocation as NSArray).filteredArrayUsingPredicate(searchPredicate)
  self.tableView.reloadData()
}

或者,您可以使用 Swift 的 filter 函数进行过滤。

func updateSearchResultsForSearchController(searchController: UISearchController)
{
  filteredPreviousLocations = previousLocation.filter { $0.locationName == searchController.searchBar.text!}
  self.tableView.reloadData()
}

因为在这两个函数中数组filteredPreviousLocations 被明确设置,也不需要调用removeAll

编辑:要在键入完整名称之前获得搜索结果,您应该过滤部分字符串而不是整个位置名称

func updateSearchResultsForSearchController(searchController: UISearchController)
{
  filteredPreviousLocations = previousLocation.filter { $0.locationName.rangeOfString(searchController.searchBar.text!, options: [.AnchoredSearch, .CaseInsensitiveSearch, .DiacriticInsensitiveSearch]) != nil}
  self.tableView.reloadData()
}

关于swift - 搜索 Controller - 将 NSPredicate 与模型一起使用时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33195181/

相关文章:

ios - 将字典保存到 UserDefaults

ios - 是否可以在 Swift 上使用 iOS 自动更正库?

ios - 使用谓词查询核心数据

ios - 使用 NSPredicate 过滤对象和键(需要拆分)

ios - SearchController改变tableView的大小

swift - UISearchController 采用了错误的 TableView

swift - 您将如何根据其值类型过滤 swift 字典?

ios - 如何在核心数据中保存明天日期任务以及如何将这些任务放入 Swift 的 TableView 中?

ios - 使用Search Controller执行搜索后退出编辑状态

search - updateSearchResults() 没有被调用