2015-08-18 63 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

相關問題