beasone
beasone

Reputation: 1085

how to update the view controller to show the search results after clicked enter button in search bar?

Now I have UISearchBar(I don't add UISearchDisplayController). Now I need: When I type some words inside UISearchBar and press enter, the CategoryListViewController should show the searching results. If I don't input anything inside the search bar, the CategoryListViewController should show all data. After typed words and click enter button, I can get the text I input. But how to show the searching results? (I use core data to store data). About the CategoryListViewController:

import Foundation
import UIKit
import CoreData
class CategoryListViewController: UIViewController,UITableViewDataSource, UITableViewDelegate,UISearchBarDelegate
{


func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    guard let count = resultController?.sections?.count else
    {
        return 0
    }

    return count
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
     if (searchCategory != nil)
     {
        return 1
     }

        guard let count = resultController?.sections?[section].numberOfObjects
        else
        {
            return 0
        }


    return count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
    let cell:UITableViewCell

    cell = tableView.dequeueReusableCellWithIdentifier("firstrow", forIndexPath: indexPath)

    if let category = resultController?.objectAtIndexPath(indexPath) as? Category, let title = category.title,let images = category.image
    {

        cell.textLabel?.text = title


        let number = images.count

      cell.detailTextLabel?.text = "Contains \(number) images"

    }

    return cell
}
@IBOutlet weak var tableView: UITableView!


@IBOutlet weak var searchView: UISearchBar!

func searchBarCancelButtonClicked(searchBar: UISearchBar)
{
    self.view.endEditing(true)
}



override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
    switch segue.identifier {
    case .Some("catSegue"):
        let indexPath = tableView.indexPathForSelectedRow!
        let viewController = segue.destinationViewController as! CatImagesViewController
        viewController.navigationItem.title = "Cat Images"

        tableView.deselectRowAtIndexPath(indexPath, animated: false)

        if let category = resultController?.objectAtIndexPath(indexPath) as? Category, /*let title = category.title,*/ let images = category.image
        {

            viewController.target_category = category
            viewController.number_of_cells = images.count

        }


    default:
        super.prepareForSegue(segue, sender: sender)
    }
}
// MARK: View Life Cycle
override func viewDidLoad() {
    super.viewDidLoad()
    tableView.delegate = self
    tableView.dataSource = self
    searchView.delegate = self

    //--------------------------------
    if (searchCategory != nil)
    {
        resultController = try? CatService.sharedCatService.catCategories(searchCategory)
    }
    else
    {
        resultController = try? CatService.sharedCatService.catCategories()

    }


}

func searchBarSearchButtonClicked(searchBar: UISearchBar) {
   // print("searchText2 \(searchBar.text)")

    searchCategory = searchBar.text
    self.viewDidLoad()
}

private var searchCategory:String?
private var resultController: NSFetchedResultsController?
private var imageController: NSFetchedResultsController?
}

About the core data part to get the searching results:

    func catCategories(searchTerm: String? = nil) throws -> NSFetchedResultsController {
let fetchRequest = NSFetchRequest(entityName: "Category")

//let fetchRequest = NSFetchRequest(namedEntity: Image.self)

if let someSearchTerm = searchTerm
{
    fetchRequest.predicate = NSPredicate(format: "title == %@", someSearchTerm )
    print("somesearchTerm is \(someSearchTerm)")
}



fetchRequest.sortDescriptors = [NSSortDescriptor(key:"title",ascending: true)]

let mainQueueContext = CoreDataService.sharedCoreDataService.mainQueueContext
let fetchResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: mainQueueContext, sectionNameKeyPath: nil, cacheName: nil)

try fetchResultsController.performFetch()
return fetchResultsController

}

Upvotes: 0

Views: 1133

Answers (1)

Mundi
Mundi

Reputation: 80265

I also like to filter "in place", i.e. without using a search controller and an overlay with search results. I usually follow this pattern.

You should set the predicate of the fetched results controller's fetch request to nil explicitly if the search term is nil or has no content.

fetchRequest.predicate = (someSearchTerm ?? "").characters.count == 0 ? nil :
     NSPredicate(format:"title BEGINSWITH %@", someSearchTerm!)

Second, you need to implement this UISearchBarDelegate method

func searchBarSearchButtonClicked(searchBar: UISearchBar) {
    searchBar.resignFirstResponder()
    someSearchTerm = searchBar.text 
    fetchedResultsController.performFetch()
    tableView.reloadData()
}

Upvotes: 1

Related Questions