ios - Swift 使用 NSFetchedResultsController 和 UISearchBarDelegate

标签 ios swift core-data uisearchbar

我正在寻找解决这个问题的合适方法。我想在我拥有的 TableView 上实现一些简单的搜索功能。

我发现的所有示例要么使用已弃用的 UISearchDisplayController,要么使用新的 UISearchController 但不使用 NSFetchedResultsController 目前这是使用 Core Data/NSFetchedResultsController

填充的

到目前为止,我已经成功地收集了用户的搜索字符串(哇!)。我知道我可能需要一个单独的 FRC 来执行搜索,但如上所述,到目前为止所有尝试都失败了。

我的类(class)符合以下协议(protocol):

class JobListController: UIViewController, UITableViewDelegate, UITableViewDataSource, NSFetchedResultsControllerDelegate, UISearchBarDelegate{

我不能使用 UITableViewController,因为我已经编写了大量现有功能,这些功能依赖于作为 UIViewController 的此类 我有两个 IBOutlets:

@IBOutlet var tblJobs : UITableView!
@IBOutlet weak var searchBar: UISearchBar!

和我的空数组来保存我的各种核心数据点点滴滴:

var workItems = [Work]()
var filteredWorkItems = [Work]()

这是我如何初始化我的 FRC 以及我的 MOC 并且我已经离开了我的第二个空的 FRC很确定在某个时候会需要它:

  let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext

lazy var fetchedResultsController: NSFetchedResultsController = {
    let workFetchRequest = NSFetchRequest(entityName: "Work")
    let primarySortDescriptor = NSSortDescriptor(key: "createdDate", ascending: true)
    let secondarySortDescriptor = NSSortDescriptor(key: "town", ascending: true)
    workFetchRequest.sortDescriptors = [primarySortDescriptor, secondarySortDescriptor]

    let frc = NSFetchedResultsController(
        fetchRequest: workFetchRequest,
        managedObjectContext: self.managedObjectContext!,
        sectionNameKeyPath: "createdDate",
        cacheName: nil)

    frc.delegate = self


    return frc
    }()

var searchResultsController: NSFetchedResultsController?

在我的 viewDidLoad 函数中,我正在为我的表和搜索栏设置委托(delegate)/数据源:

  tblJobs.delegate = self
  tblJobs.dataSource = self
  searchBar.delegate = self

这里是 searchBar 函数,这是我要做的。 stringMatch 变量是上一次尝试遗留下来的,我希望能够在这里通过大量不同的参数进行搜索,但如果我能只使用一个参数,那将是一个坚实的开始。

func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
    println("Search text is \(searchText)")
    self.filteredWorkItems = self.workItems.filter({( work: Work) -> Bool in
        //
        let stringMatch = work.postcode.rangeOfString(searchText)
        return stringMatch != nil
    })

    if(filteredWorkItems.count == 0){
        searchActive = false;
    } else {
        searchActive = true;
    }
    self.tblJobs.reloadData()
}

这是我的 cellForRowAtIndexPath 函数,用于显示我如何从 fetchedResultsController 中提取数据

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
    let cell =  self.tblJobs.dequeueReusableCellWithIdentifier(
        "JobCell", forIndexPath: indexPath)
        as! JobTableViewCell

    let workItem = fetchedResultsController.objectAtIndexPath(indexPath) as! Work



 //...

    return cell
}

所以你可以看到我在这里做了一些事情,最终我想弄清楚我如何使用我新获得的 searchText 字符串来查询我的 FRC,然后在 View 中正确过滤结果。

更新:

我试图将搜索字符串添加到 FRC 中的 NSPredicate 中,如下所示:

lazy var fetchedResultsController: NSFetchedResultsController = {

   ../


    workFetchRequest.predicate = NSPredicate(format:"title contains[cd] %@", savedSearchTerm!)

   //...
    return frc
    }()

这导致 “JobListController.Type”没有名为“savedSearchTerm”的成员

在我类(class)的顶部,我是这样设置的:

var savedSearchTerm: NSString?

所以不确定我做错了什么?

最佳答案

根据您的代码,我假设您希望使用相同 TableView 来显示结果。因此,您只需要使用基于搜索词的新过滤器更新您的 FRC。

将搜索词存储在变量中。在 FRC 工厂函数中,包含谓词,如下所示:

request.predicate = searchText?.characters.count > 0 ?
 NSPredicate(format:"title contains[cd] %@", searchText!) : nil

当文本改变时,重置FRC并重新加载。

fetchedResultsController = nil
tableView.reloadData()

如果您有其他过滤器,例如范围按钮,请向谓词添加其他术语。

关于ios - Swift 使用 NSFetchedResultsController 和 UISearchBarDelegate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32072723/

相关文章:

ios - AVPlayer 控件无法正常工作

SwiftUI 框架大小

ios - 如何将多个对象保存到关系实体中。 Xcode

ios - 为什么 NSOperationQueue.mainQueue.maxConcurrentOperationCount 设置为 1

ios - 如何在 swift 2 中解析未知的 json 数据类型

ios - 我应该在 iOS 应用程序中的什么位置存储默认字符串列表?

ios - iCloud 核心数据同步设置

swift - 总结核心数据中的 bool 值与 nsnumbers

ios - 如何以编程方式使用 UIGraphicsImageRenderer 拍摄高质量的屏幕截图?

ios - 离线时在 UIWebView 后面显示文本