2015-08-18 30 views
2

我正在寻找一个体面的解决方案来解决这个问题。我想在我拥有的TableView上实现一些简单的搜索功能。Swift使用NSFetchedResultsController和UISearchBarDelegate

我发现无论是使用已弃用UISearchDisplayController或使用新UISearchController但没有NSFetchedResultsController 目前这是使用填充Core Data/NSFetchedResultsController

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

我的类是符合以下协议:

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

我不能使用UITableViewController,因为我已经写的,它依赖于这个类是现有的功能加载一个UIViewController 我有我的两个IBOutlets

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

和我的空数组来保存我的各种Core Data位和鲍勃:

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功能我设置为我的表代表/数据源和搜索栏:

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中正确过滤。

更新:

我试图搜索字符串添加到我的NSPredicateFRC像这样:

lazy var fetchedResultsController: NSFetchedResultsController = { 

    ../ 


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

    //... 
    return frc 
    }() 

导致'JobListController.Type' does not have a member named 'savedSearchTerm'

在我班上的第一名我已经这样设置:

var savedSearchTerm: NSString? 

所以不知道我在做什么错了?

回答

7

从您的代码中,我假设您想使用相同的表视图来显示结果。所以你只需要根据搜索词使用新的过滤器更新FRC。

将搜索词存储在变量中。在FRC工厂功能中,包括谓词,如下所示:

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

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

fetchedResultsController = nil 
tableView.reloadData() 

如果您有其他过滤器(如范围按钮),则向谓词中添加其他术语。

+0

使用单独的表视图有什么好处吗?我无法想象如何有单独的表视图工作? – dyatesupnorth

+1

通常它是一个有点透明的覆盖表格视图,它被叠加。如果您使用自定义单元格不显示原始表格视图中的丰富数据,但是只搜索正在搜索的文本,这会非常有用。 – Mundi

+0

ii'm有几个问题,首先我不能从我的懒惰var fetchedResultsController中访问我的searchTerm变量,也无法将该fetchedResultsController设置为零 – dyatesupnorth

相关问题