Reputation: 123
My question is I have implemented UISearchController
in Swift 3 when I tried to filter it's easily filtered simple array but my case is little bit different I have one array which I fetch all the data from SQLite database
in class so its array of class
managerControlClassArray
which has all the content of the class array.
I want to filter the content in updateSearchResults
delegate method but it's really difficult and stuck I did to much research and after not getting my desired query I found StackOverflow is very useful and question it if someone help's me, I would be grateful.
Some Code Logic:
manager = ModelManager.getInstance().getAllManager()
// I get all the objects using singleton
//manager class has following data
id, title, designation, salary
//In TableView i want to display data by using that
let managerVar = manager[indexPath.row]
cell.textLabel.text = managerVar.title
Edit:
MasterTableViewController.swift
import UIKit
class MasterTableViewController: UITableViewController, UISplitViewControllerDelegate, UISearchResultsUpdating {
var array: NSMutableArray! = NSMutableArray()
var managerArray = [foodManager]()
var filteredmanagerArray = [foodManager]()
var searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
// Set the AppTitle using Config File
self.title = GL_Appname
managerArray = ModelManager.getInstance().getAllManagers()
filteredmanagerArray = managerArray
//copyTitleArrayForSearch()
self.tableView.reloadData()
self.splitViewController!.delegate = self;
self.splitViewController!.preferredDisplayMode = UISplitViewControllerDisplayMode.allVisible
//Seach Result Controller
self.searchController.searchResultsUpdater = self
self.searchController.dimsBackgroundDuringPresentation = false
self.searchController.definesPresentationContext = true
self.searchController.searchBar.sizeToFit()
self.tableView.tableHeaderView = self.searchController.searchBar
}
/* func copyTitleArrayForSearch(){
for i in 0..<managerArray.count{
let fd = managerArray[i]
//titleArray.append(fd.title)
}
} */
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat{
return 60
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searchController.isActive{
return filteredmanagerArray.count
}
else{
return managerArray.count
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.adjustsFontSizeToFitWidth = true
cell.textLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping
cell.textLabel?.numberOfLines = 3
cell.textLabel?.textColor = UIColor.black
cell.textLabel?.font = UIFont(name: "ChalkboardSE-Light", size: 14.0)
if searchController.isActive {
let fra = filteredmanagerArray[indexPath.row]
cell.textLabel?.text = fra.title.uppercased()
}
else{
let fd = managerArray[indexPath.row]
cell.textLabel?.text = fd.title.uppercased()
}
return cell
}
func updateSearchResults(for searchController: UISearchController) {
self.tableView.reloadData()
self.filteredRecipeArray.removeAll(keepingCapacity: false)
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %@", searchController.searchBar.text!)
let array = (self.filteredRecipeArray as NSArray).filtered(using: searchPredicate)
self.filteredRecipeArray = array as! [foodRecipe]
self.tableView.reloadData()
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("DidSelect index Path: \(indexPath.row)")
//print("Filtered Manager Index: \(filteredmanagerArray[indexPath.row]))")
self.performSegue(withIdentifier: "showDetail", sender: self)
}
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showDetail" {
let index = self.tableView.indexPathForSelectedRow! as IndexPath
let nav = segue.destination as! UINavigationController
let vc = nav.viewControllers[0] as! DetailViewController
if searchController.isActive {
print("Manager Array Index: \(managerArray[index.row])")
//var currentFilteredIndex = filteredmanagerArray[(indexPath as NSIndexPath).row]
print("Filtered Manager Array Index: \(filteredmanagerArray[index.row])"
}
else{
vc.selectedmanagerArray = [managerArray[index.row]]
}
//vc.titleText = self.array.object(at: (index as NSIndexPath).row) as! String
self.tableView.deselectRow(at: index, animated: true)
}
}
// MARK: - UISplitViewControllerDelegate
func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool {
return true
}
}
Manager.swift
class Manager: NSObject{
var id: String = String()
var title: String = String()
var ManagerDesignation: String = String()
}
Thanks.
Bye.
Upvotes: 1
Views: 3603
Reputation: 994
Can we just use Swift's built in filter
method?
func updateSearchResults(for searchController: UISearchController) {
self.tableView.reloadData()
self.filteredRecipeArray.removeAll(keepingCapacity: false)
guard let searchText = searchController.searchBar.text else {
return
}
let array = managerArray.filter {
return $0.id.range(of: searchText) != nil ||
$0.title .range(of: searchText) != nil ||
$0.ManagerDesignation.range(of: searchText) != nil
}
self.filteredRecipeArray = array
self.tableView.reloadData()
}
EDIT
Updated the answer to latest Swift 3 syntax
Upvotes: 2