UISearchController crash when selected - ios

I tried to implement a UISearchController into my ViewController. However, when I try to open up the Controller from a button it crashes the application and there is no error given to me from Xcode. I am using Backendless to store users and to retrieve them. I want to search through them.
Here is my code. I don't know what I am doing wrong :/ I would really appreciate the help.
import UIKit
protocol ChooseUserDelegate {
func chreatChatroom(withUser: BackendlessUser)
}
class ChooseUserViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchResultsUpdating {
#IBOutlet weak var tableView: UITableView!
var delegate: ChooseUserDelegate!
var users: [BackendlessUser] = []
var filteredUsers = [BackendlessUser]()
var resultSearchController: UISearchController!
override func viewDidLoad() {
super.viewDidLoad()
loadUsers()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK: UITableviewDataSorce
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func updateSearchResultsForSearchController(searchController: UISearchController) {
self.filteredUsers.removeAll(keepCapacity: false)
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %#", searchController.searchBar.text!); let array = (self.users as NSArray).filteredArrayUsingPredicate(searchPredicate)
self.filteredUsers = array as! [BackendlessUser]
self.tableView.reloadData()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if resultSearchController.active
{
return self.filteredUsers.count
} else {
return users.count
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell?
if self.resultSearchController.active
{
let userFiltered = filteredUsers[indexPath.row]
cell!.textLabel?.text = userFiltered.name
} else {
let user = users[indexPath.row]
cell!.textLabel?.text = user.name
}
return cell!
}
//MARK: UITableviewDelegate
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let user = users[indexPath.row]
delegate.chreatChatroom(user)
tableView.deselectRowAtIndexPath(indexPath, animated: true)
self.dismissViewControllerAnimated(true, completion: nil)
}
//MARK: IBactions
#IBAction func cancelButtonPressed(sender: AnyObject) {
self.dismissViewControllerAnimated(true, completion: nil)
}
//MARK: Load Backendless Users
func loadUsers() {
let whereClause = "objectId != '\(backendless.userService.currentUser.objectId)'"
let dataQuery = BackendlessDataQuery()
dataQuery.whereClause = whereClause
let dataStore = backendless.persistenceService.of(BackendlessUser.ofClass())
dataStore.find(dataQuery, response: { (users : BackendlessCollection!) -> Void in
self.users = users.data as! [BackendlessUser]
self.resultSearchController = UISearchController(searchResultsController: nil)
self.resultSearchController.searchResultsUpdater = self
self.resultSearchController.dimsBackgroundDuringPresentation = false
self.resultSearchController.searchBar.sizeToFit()
self.tableView.tableHeaderView = self.resultSearchController.searchBar
self.tableView.reloadData()
}) { (fault : Fault!) -> Void in
print("Error, couldnt retrieve users: \(fault)")
}
}
}

Your resultSearchController is nil before it is used. It's set in a closure that almost certainly sets it after it's needed when setting up the view. To fix it, just move this initialization code to something earlier like viewDidLoad():
self.resultSearchController = UISearchController(searchResultsController: nil)
self.resultSearchController.searchResultsUpdater = self
self.resultSearchController.dimsBackgroundDuringPresentation = false
self.resultSearchController.searchBar.sizeToFit()
self.tableView.tableHeaderView = self.resultSearchController.searchBar

Related

DidSelectRow method not called

Hi guys I have been trying for few days no answer found . I have already implemented UITableViewDelegate and UITableViewDataSource before raising this question my didSelectRowAt and didDeselectRowAt, both the methods are not working.
class SearchClass: UIViewController, UITableViewDataSource,UITableViewDelegate, UISearchBarDelegate {
#IBOutlet weak var myTableView: UITableView!
#IBOutlet weak var mySearchBar: UISearchBar!
var objects:PFObject!
var searchResults = [String]()
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.navigationController?.navigationBar.topItem?.title = "Search"
self.navigationController?.navigationBar.barTintColor = UIColor.white
self.navigationController?.navigationBar.backgroundColor = UIColor.black
self.navigationController?.navigationBar.tintColor = UIColor.black
self.searchResults.removeAll()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.myTableView.dataSource = self
self.mySearchBar.delegate = self
self.myTableView.delegate = self
self.navigationController?.extendedLayoutIncludesOpaqueBars = true
//self.myTableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar)
{
searchBar.resignFirstResponder()
// self.navigationController?.navigationBar.isHidden = false
self.mySearchBar.endEditing(true)
print("Search word = \(searchBar.text)")
let query = PFQuery(className:"myClass")
//let newText = searchBar.autocapitalization
searchBar.autocapitalizationType = .none
searchBar.text = searchBar.text?.localizedLowercase
query.whereKey("collegeNickName", contains: searchBar.text)
query.findObjectsInBackground { (results, error) in
if error == nil {
if let objects = results {
self.searchResults.removeAll(keepingCapacity: true)
for object in objects {
let firstName = object.object(forKey: "myName") as! String
let image = object.object(forKey: "myImage") as! PFFile
// let lastName = object.object(forKey: "myPlace") as! String
// let fullName = firstName + " " + lastName
self.searchResults.append(firstName)
print(self.searchResults[0])
DispatchQueue.main.async {
self.myTableView.reloadData()
self.mySearchBar.resignFirstResponder()
}
}
}
} else {
let myAlert = UIAlertController(title:"Alert", message:error?.localizedDescription, preferredStyle:UIAlertControllerStyle.alert)
let okAction = UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: nil)
myAlert.addAction(okAction)
self.present(myAlert, animated: true, completion: nil)
return
}
}
}
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
//self.navigationController?.navigationBar.isHidden = true
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return searchResults.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
myTableView.register(UITableViewCell.self, forCellReuseIdentifier: "myCell")
let myCell = myTableView.dequeueReusableCell(withIdentifier: "myCell")
myCell?.textLabel?.text = searchResults[indexPath.row]
print(searchResults[indexPath.row])
return myCell!
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("Hi")
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar)
{
mySearchBar.resignFirstResponder()
mySearchBar.text = ""
myTableView.reloadData()
}
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
//self.mySearchBar.resignFirstResponder()
//self.mySearchBar.endEditing(true)
self.definesPresentationContext = true
}
#IBAction func refreshButtonTapped(sender: AnyObject) {
mySearchBar.resignFirstResponder()
mySearchBar.text = ""
self.searchResults.removeAll(keepingCapacity: false)
self.myTableView.reloadData()
}
}
Also it implements a searchView I'm getting what I want to search but unable use select and deselect methods in my class.
self.myTableView.dataSource = self
self.myTableView.delegate = self
<--- add this.
Noticed that you've set delegate in the storyboard as view instead of your UIViewController
see Discover - that's mine UViewController
In Interface Builder
Connect dataSource and delegate of My Table View to SearchClass
Then you can delete redundant self.myTableView.dataSource = self in SearchClass
Consider that connections in Interface Builder are more efficient than in code.
Declaration of cell is wrong. you have done this below code
let myCell = myTableView.dequeueReusableCell(withIdentifier: "myCell")
Right format
let myCell = tableView.dequeueReusableCell(withIdentifier: "myCell")
Reason: When you use dequeue property, then UITableView dequeue its cell by the param it got from the method
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
see there is a param tableView but you are dequeing by the outllet of UITableView.

SearchController issue, when search the displayController shows a spacing from the Searchbar

The issue is this:
In the storyboard, I must uncheck the Adjust Scroll View Insets, because if not do this, I will get a other issue(https://stackoverflow.com/questions/40974647/uisearchcontroller-issue-nslayoutattribute-do-not-work-in-real-device), and I don't know this if is affect the issue here.(I test in simulator, if check Adjust Scroll View Insets, the issue here will not appear )
My code
import UIKit
import SVProgressHUD
class ChooseStoreViewController: UIViewController,UISearchBarDelegate, UITableViewDelegate, UITableViewDataSource, UISearchResultsUpdating {
#IBOutlet weak var tableView: UITableView!
var ori_dataSource: [StoreListModel] = [StoreListModel]()
var dataSource = [String]()
var filterdDataSource = [String]()
var resultSearchController = UISearchController()
var choosedStore:StoreListModel? = nil
var userInfoFromChooseTerant:[String:Any]?
#IBOutlet weak var top_constraint: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
initData()
initUI()
}
// MARK: - view life
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.isNavigationBarHidden = false
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.navigationController?.isNavigationBarHidden = true
}
func initData() {
self.resultSearchController = UISearchController(searchResultsController: nil)
self.resultSearchController.searchResultsUpdater = self
self.resultSearchController.dimsBackgroundDuringPresentation = false
self.resultSearchController.searchBar.sizeToFit()
self.resultSearchController.searchBar.placeholder = "search"
self.resultSearchController.searchBar.tintColor = UIColor.black
self.resultSearchController.searchBar.delegate = self
self.tableView.tableHeaderView = self.resultSearchController.searchBar
let nib = UINib(nibName: "TerantListCell", bundle: nil)
// Required if our subclasses are to use: dequeueReusableCellWithIdentifier:forIndexPath:
//tableView.register(nib, forCellReuseIdentifier: "TerantListCell")
self.tableView.register(nib, forCellReuseIdentifier: "TerantListCell")
self.tableView.tableFooterView = UIView.init()
self.tableView.reloadData()
networkForStoreList()
}
func initUI() {
let backNavItem:UIBarButtonItem = UtilSwift.addBackButtonItem(nil, controlelr: self)
backNavItem.action = #selector(navBack)
// print(userInfoFromChooseTerant!)
tableView.separatorStyle = UITableViewCellSeparatorStyle.none
}
// 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?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
let chooseRole: ChooseRoleViewController = segue.destination as! ChooseRoleViewController
chooseRole.userInfoFromChooseStore = self.userInfoFromChooseTerant
}
// MARK: - search delegate
func searchBarCancelButtonClicked() {
for item:NSLayoutConstraint in self.tableView.constraints {
self.view.setNeedsLayout()
if item.firstAttribute == NSLayoutAttribute.top {
item.constant = 0
}
}
}
// MARK: - searchbar delegate
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
searchBar.setValue("cancel", forKey:"_cancelButtonText")
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
}
// MARK: - private methods
func navBack() {
_ = self.navigationController?.popViewController(animated: true)
}
// MARK: - actions
#IBAction func unwindToChooseStoreVCFromChooseRole(segue: UIStoryboardSegue){
}
#IBAction func nextStepAction(_ sender: UIButton) {
/*if choosedStore == nil {
let lml_alert: LMLDropdownAlertView = LMLDropdownAlertView.init(frame: self.view.bounds)
lml_alert.showAlert(title: Global.hint, detail_Title: "select", cancleButtonTitle: "cacnel", confirmButtonTitle: "confirm", action: { (button) in
})
return
}*/
self.resultSearchController.isActive = false
if self.choosedStore != nil {
_ = self.userInfoFromChooseTerant?.updateValue(self.choosedStore!.userId, forKey: "store_id")
}
self.performSegue(withIdentifier: "ChooseStoreVCToChooseRoleVC", sender: self)
}
// MARK: - network
func networkForStoreList() {
let params:[String:String] = [
"createTime":"-1",
"userId" : self.userInfoFromChooseTerant!["affiliated_id"] as! String
]
// url_terantList
Mysevers.afpost(withHud: true, andAddressname: Global.url_listStore, parmas: params, requestSuccess: { (result) in
let stateCode = UtilSwift.getNetStateCode(result: result as Any, key: Global.net_key_stateCode)
if stateCode == 0 {
let storeArr:[[String : Any]] = UtilSwift.getNetAnyObject(result: result as Any, key: "list") as! [[String : Any]] // Global.net_key_bussines
//self.ori_dataSource = terantArr
for item:[String: Any] in storeArr {
let store_list_model: StoreListModel = StoreListModel.initStoreListModelWithDic(dic: item)
self.ori_dataSource.append(store_list_model)
}
for item:StoreListModel in self.ori_dataSource {
self.dataSource.append(item.name)
}
self.tableView.reloadData()
}else if stateCode == -1 {
SVProgressHUD.showError(withStatus: "err")
}
}, failBlcok: {
SVProgressHUD.showError(withStatus: "err")
})
}
// MARK: - tableView
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if self.resultSearchController.isActive {
return filterdDataSource.count
}else {
return dataSource.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: TerantListCell = tableView.dequeueReusableCell(withIdentifier: "TerantListCell", for: indexPath) as! TerantListCell
if self.resultSearchController.isActive {
cell.title_label.text = self.filterdDataSource[indexPath.row]
}else {
cell.title_label?.text = self.dataSource[indexPath.row]
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.choosedStore = self.ori_dataSource[indexPath.row]
}
// MARK: - regexp
func updateSearchResults(for searchController: UISearchController) {
self.filterdDataSource.removeAll(keepingCapacity: false)
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %#", searchController.searchBar.text!)
let array = (self.dataSource as NSArray).filtered(using: searchPredicate)
self.filterdDataSource = array as! [String]
self.tableView.reloadData()
}
}
Go to ".storyboard" file where "ChooseStoreViewController" exist. Then click on UITableView and change tableView constraints as follows:
Check Top Space constraint.

found nil while trying to segue away from a tableView

I'm getting errors whenever I try to reference the viewTable in the viewDidLoad AFTER I click on a cell to transition with the segue. Thanks a lot!!
Basically I can't use the segue unless I comment out the tableview references in view did load... but I need those in order to use the search bar and im sure it will cause problems on the way back...
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet var tableView: UITableView! {
didSet {
print("tableView is set")
}
}
let searchController = UISearchController(searchResultsController: nil)
let textCellIdentifier = "TextCell"
var buildings: [(String,String)] = []
var filteredBuildings = [(String,String)]()
var goToIndex: Int?
override func viewDidLoad() {
super.viewDidLoad()
print(tableView)
var buildingTuples = loadBuildings()
for tuple in buildingTuples {
self.buildings.append(tuple)
}
self.goToIndex = -1
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
definesPresentationContext = true
tableView!.tableHeaderView = searchController.searchBar
}
func filterContentForSearchText(searchText: String, scope: String = "All") {
filteredBuildings = buildings.filter { building in
return building.0.lowercaseString.containsString(searchText.lowercaseString)
}
self.tableView.reloadData()
}
// MARK: UITextFieldDelegate Methods
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//return self.buildings.count
if searchController.active && searchController.searchBar.text != "" {
return filteredBuildings.count
}
return buildings.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
/*
let cell = tableView.dequeueReusableCellWithIdentifier(textCellIdentifier, forIndexPath: indexPath)
let row = indexPath.row
cell.textLabel?.text = buildings[row].0
return cell
*/
let cell = tableView.dequeueReusableCellWithIdentifier(textCellIdentifier, forIndexPath: indexPath)
let tuple: (String, String)
if searchController.active && searchController.searchBar.text != "" {
tuple = filteredBuildings[indexPath.row]
} else {
tuple = buildings[indexPath.row]
}
cell.textLabel?.text = tuple.0
return cell
}
// MARK: UITableViewDelegate Methods
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
//tableView.deselectRowAtIndexPath(indexPath, animated: true)
let row = indexPath.row
self.goToIndex = indexPath.row
self.performSegueWithIdentifier("MainToLocation", sender: self)
//print(buildings[row].0)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "MainToLocation" {
let locationViewController = (segue.destinationViewController as! LocationViewController)
locationViewController.building = self.buildings[self.goToIndex!]
}
}
extension ViewController: UISearchResultsUpdating {
func updateSearchResultsForSearchController(searchController: UISearchController) {
filterContentForSearchText(searchController.searchBar.text!)
}
}
You can try this..
let destinationVC = self.storyboard!.instantiateViewControllerWithIdentifier("viewController") as! NextViewController
var alreadyPushed = false
if let vc = self.navigationController?.viewControllers {
for viewController in vc {
if let viewController = viewController as? NextViewController {
self.navigationController?.popToViewController(viewController, animated: true)
print("Push your controller")
alreadyPushed = true
break
}
}
}
if alreadyPushed == false {
self.navigationController?.pushViewController(destinationVC, animated: true)
}

Cannot subscript a value of type dictionary with an index of type Int

Working on an IOS app(swift 1.2, Xcode 6.3), I'm implementing the UISearchController in a ViewController and I'm getting an error in the data source method (cellForRowAtIndexPath) when I try return a cell for a table view, becouse I don't know to obtain an indexpath.row from a dictionary. The error is Cannot subscript a value of type [String : AnyObject] with an index of type Int and the code of the view controller is:
import Foundation
import UIKit
class UsersViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet var tableview:UITableView!
let apiClient = ApiClient()
var users: [User]!
var searchArray:[AnyObject] = [AnyObject](){
didSet {self.tableview.reloadData()}
}
var usersSearchController = UISearchController()
override func viewDidLoad() {
super.viewDidLoad()
self.usersSearchController = ({
// Two setups provided below:
// Setup One: This setup present the results in the current view.
let controller = UISearchController(searchResultsController: nil)
controller.searchResultsUpdater = self
controller.hidesNavigationBarDuringPresentation = false
controller.dimsBackgroundDuringPresentation = false
controller.searchBar.searchBarStyle = .Minimal
controller.searchBar.sizeToFit()
self.tableview.tableHeaderView = controller.searchBar
return controller
})()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
println("UsersController viewWillAppear")
apiClient.usersService.getList() { users, error in
if users != nil {
self.users = users
self.tableview?.reloadData()
} else {
println("error: \(error)")
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if ( self.usersSearchController.active){
return self.searchArray.count ?? 0
} else {
return self.users?.count ?? 0
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("userObjectCell") as! UserTableViewCell
if (self.usersSearchController.active){
cell.userObject = self.searchArray[indexPath.row] as? User//HERE IS THE ERROR
return cell
} else {
cell.userObject = self.users?[indexPath.row]
return cell
}
}
}
extension UsersViewController: UITableViewDelegate
{
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
}
extension UsersViewController: UISearchResultsUpdating
{
func updateSearchResultsForSearchController(searchController: UISearchController)
{
// self.searchArray.removeAll(keepCapacity: false)
//
// let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %#", searchController.searchBar.text)
// let array = (self.users as NSArray).filteredArrayUsingPredicate(searchPredicate)
// self.searchArray = array as! [String: AnyObject]
}
}
Dictionaries don't have indexes, they have keys. You may want to consider a method of parsing your dictionary data and putting it into an ordered list, like an Array, so your data will appear in the same place. (Dictionaries are not ordered).

How to filter object array in updateSearchResultsForSearchController when using UISearchController?

My search controller class is as following:
class FeastSearchTableViewController: UITableViewController, UISearchResultsUpdating {
var feastEntries = [FeastEntry]()
var filteredFeasts = [FeastEntry]()
/* let tableData = ["One","Two","Three","Twenty-One"]
var filteredTableData = [String]()*/
var resultSearchController = UISearchController()
override func viewDidLoad() {
super.viewDidLoad()
self.resultSearchController = ({
let controller = UISearchController(searchResultsController: nil)
controller.searchResultsUpdater = self
controller.dimsBackgroundDuringPresentation = false
controller.searchBar.sizeToFit()
self.tableView.tableHeaderView = controller.searchBar
return controller
})()
self.feastEntries = [FeastEntry(category:"Chocolate", name:"chocolate Bar"),
FeastEntry(category:"Chocolate", name:"chocolate Chip"),
FeastEntry(category:"Chocolate", name:"dark chocolate"),
FeastEntry(category:"Hard", name:"lollipop"),
FeastEntry(category:"Hard", name:"candy cane"),
FeastEntry(category:"Hard", name:"jaw breaker"),
FeastEntry(category:"Other", name:"caramel"),
FeastEntry(category:"Other", name:"sour chew"),
FeastEntry(category:"Other", name:"gummi bear")]
// Reload the table
self.tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// 2
if (self.resultSearchController.active) {
return self.filteredFeasts.count
}
else {
return self.feastEntries.count
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let feasts = self.feastEntries[indexPath.row]
let cell = tableView.dequeueReusableCellWithIdentifier("TimelineCellPhoto") as! TimelineCell
cell.typeImageView.image = UIImage(named: "timeline-photo")
cell.profileImageView.image = UIImage(named: "profile-pic-2")
cell.nameLabel.text = feasts.name
cell.photoImageView?.image = UIImage(named: "dish")
cell.dateLabel.text = "2 mins ago"
cell.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("feastDetail", sender: tableView)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "feastDetail" {
let candyDetailViewController = segue.destinationViewController as! UIViewController
}
}
func updateSearchResultsForSearchController(searchController: UISearchController)
{
filteredFeasts.removeAll(keepCapacity: false)
let searchPredicate = NSPredicate(format: "category CONTAINS[c] %#", searchController.searchBar.text)
//let array = (feastEntries as NSMutableArray).filteredArrayUsingPredicate(searchPredicate)
/* let array = (feastEntries as NSArray).filteredArrayUsingPredicate(searchPredicate)
filteredFeasts = array as! [String]
*/
self.tableView.reloadData()
}
}
struct FeastEntry {
let category : String
let name : String
}
I have two requirements. First one is as how can I filter feastEntries array on the basis of category inside updateSearchResultsForSearchController.
Second is as how can I implement scope bar filter for this scenario.
Check filter method in swift...using this you can filter any collection type,and you could write something like this:
let filteredEntry = self.feastEntries.filter { $0.0 == “Chocolate”//filter condition }
ScopeBar Implementation:
Create a segmented control with chocolate,hard and other segment ...
Create an IBaction for that segmented control depending on selected segment apply filter on feastEntries array as shown above.

Resources