搜索控制器 - 使用NSPredicate与模型的问题

时间:2015-10-18 06:54:28

标签: swift nspredicate uisearchcontroller

我有一个表视图,从我的服务器获取json数据。 现在我想使用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 } } 添加搜索栏。在搜索之前正确显示单元格(自定义):

enter image description here

但是当我开始输入时,没有显示任何内容。这是代码:

MODEL

 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()
}

然后在PreviousLocationsViewControllors

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]`

进入这个

Cannot assign a value of type '[String]' to a value of type '[PreviousLocations]'

This教程中所述,我收到错误  Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode("+15555551234")); Cursor phone =getContentResolver().query(uri, new String[]{ContactsContract.PhoneLookup.DISPLAY_NAME}, null, null, null);

1 个答案:

答案 0 :(得分:2)

属性的类型明确定义为[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()
}