My search is working correctly except the display is not working as expected. When I am performing a search, the last search result is slightly cut off and the portion of the display is all gray. I would expect it to remain the same background color as the rows.. Any help would be appreciated.
EDIT:
import UIKit
import Foundation
// For search
extension MasterViewController: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
filterContentForSearchText(searchText: searchController.searchBar.text!)
}
}
class MasterViewController: UITableViewController {
let searchController = UISearchController(searchResultsController: nil)
var filteredFighters = [Fighter]()
var detailViewController: DetailViewController? = nil
var objects = [Any]()
// Creates array of fighters
var fighterArray = [Fighter]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.navigationItem.leftBarButtonItem = self.editButtonItem
if let split = self.splitViewController {
let controllers = split.viewControllers
self.detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController
}
// Access all the data from JSON
let JR = JSONReceiver()
fighterArray = JR.populateFighterJSONArray()
// Search related
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
definesPresentationContext = true
tableView.tableHeaderView = searchController.searchBar
navigationItem.title = "UFC Champions"
self.navigationController?.navigationBar.barTintColor = UIColor.black
self.navigationController?.navigationBar.tintColor = UIColor.white
self.navigationController?.navigationBar.titleTextAttributes = [ NSForegroundColorAttributeName : UIColor.white, NSFontAttributeName: UIFont(name: "Arial", size: 26)!]
}
// FOr search
func filterContentForSearchText(searchText: String, scope: String = "All") {
filteredFighters = fighterArray.filter { fighter in
return fighter.name.lowercased().contains(searchText.lowercased())
}
tableView.reloadData()
}
override func viewWillAppear(_ animated: Bool) {
self.clearsSelectionOnViewWillAppear = self.splitViewController!.isCollapsed
super.viewWillAppear(animated)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/* DONT BELIEVE THIS IS NEEDED - DO NOT SEE IN PROFESSORS CODE
func insertNewObject(_ sender: Any) {
objects.insert(NSDate(), at: 0)
let indexPath = IndexPath(row: 0, section: 0)
self.tableView.insertRows(at: [indexPath], with: .automatic)
} */
// MARK: - Segues
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Determines which row was selected (e.g. which fighters, say element 1 points to fighter1)
if segue.identifier == "showDetail" {
if let indexPath = self.tableView.indexPathForSelectedRow {
// let stud = StudentsArray[indexPath.row]
let fighter: Fighter
if searchController.isActive && searchController.searchBar.text != "" {
fighter = filteredFighters[indexPath.row]
} else {
fighter = fighterArray[indexPath.row]
}
let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController
// Makes sure selected student points to the correct controller
controller.detailItem = fighter
controller.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem
controller.navigationItem.leftItemsSupplementBackButton = true
}
}
}
// MARK: - Table View
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searchController.isActive && searchController.searchBar.text != "" {
return filteredFighters.count
}
return fighterArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let fighter: Fighter
if searchController.isActive && searchController.searchBar.text != "" {
fighter = filteredFighters[indexPath.row]
} else {
fighter = fighterArray[indexPath.row]
}
cell.textLabel!.text = fighter.name
cell.detailTextLabel?.text = fighter.record
cell.imageView?.image = UIImage(named: fighter.fighterImage)
self.tableView .sizeToFit()
// cell.detailTextLabel?.text = "fighterTest"
return cell
}
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return false
}
}
Related
I am making a simple tableview with a customCell. and a searchBar above. but getting a strange behavior from tableView. customCell is showing but above it defaultCell is showing as well and data is getting populated into the defaultCell though i am setting data on my customCell.
this is the output i am getting
https://i.imgur.com/xsTIsiz.png
if you look at it closely you will see my custom cell UI is showing under the default cell.
My custom cell:
https://i.imgur.com/J4UpRle.png
This is my code from viewcontroller
import UIKit
class SuraSearchController: UIViewController {
let searchController = UISearchController(searchResultsController: nil)
let reciters = [Reciter(name: "Abdul Basit Abdus Samad", downloadUrl: ""),
Reciter(name: "Abdul Rahman Al-Sudais", downloadUrl: ""),
Reciter(name: "Ali Bin Abdur Rahman Al Huthaify", downloadUrl: ""),
Reciter(name: "Mishary Rashid Alafasy", downloadUrl: ""),
Reciter(name: "Cheik Mohamed Jibril", downloadUrl: ""),
Reciter(name: "Mohamed Siddiq El-Minshawi", downloadUrl: ""),
Reciter(name: "Mahmoud Khalil Al-Hussary", downloadUrl: ""),
Reciter(name: "Ibrahim Walk (English Only)", downloadUrl: ""),
Reciter(name: "Abu Bakr Al Shatri", downloadUrl: "")]
var filteredReciters = [Reciter]()
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// definesPresentationContext = true
initNavBar()
initTableView()
// Do any additional setup after loading the view.
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.navigationController?.setNavigationBarHidden(true, animated: animated)
}
func initNavBar() {
// show navbar
self.navigationController?.setNavigationBarHidden(false, animated: true)
// set search bar delegates
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
// Customize Search Bar
searchController.searchBar.placeholder = "Search Friends"
let myString = "Cancel"
let myAttribute = [ NSAttributedStringKey.foregroundColor: UIColor.white ]
UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).title = myString
UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).setTitleTextAttributes(myAttribute, for: .normal)
if #available(iOS 11.0, *) {
let scb = searchController.searchBar
scb.tintColor = UIColor.white
scb.barTintColor = UIColor.white
if let textfield = scb.value(forKey: "searchField") as? UITextField {
textfield.textColor = UIColor.blue
if let backgroundview = textfield.subviews.first {
// Background color
backgroundview.backgroundColor = UIColor.white
// Rounded corner
backgroundview.layer.cornerRadius = 10
backgroundview.clipsToBounds = true
}
}
}
// Set search bar on navbar
navigationItem.searchController = searchController
navigationItem.hidesSearchBarWhenScrolling = false
}
func initTableView() {
tableView.dataSource = self
tableView.delegate = self
tableView.register(UINib(nibName: "SuraSearchCell", bundle: nil), forCellReuseIdentifier: "SuraSearchCell")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func searchBarIsEmpty() -> Bool {
// Returns true if the text is empty or nil
return searchController.searchBar.text?.isEmpty ?? true
}
func filterContentForSearchText(_ searchText: String, scope: String = "All") {
filteredReciters = reciters.filter({( reciter : Reciter) -> Bool in
return reciter.name.lowercased().contains(searchText.lowercased())
})
tableView.reloadData()
}
func isFiltering() -> Bool {
return searchController.isActive && !searchBarIsEmpty()
}
/*
// 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.
}
*/
}
extension SuraSearchController: UITableViewDataSource, UITableViewDelegate {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if isFiltering() {
return filteredReciters.count
}
return reciters.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "SuraSearchCell", for: indexPath) as? SuraSearchCell {
let candy: Reciter
if isFiltering() {
candy = filteredReciters[indexPath.row]
} else {
candy = reciters[indexPath.row]
}
cell.textLabel!.text = candy.name
return cell
}
return UITableViewCell()
}
}
extension SuraSearchController: UISearchResultsUpdating {
// MARK: - UISearchResultsUpdating Delegate
func updateSearchResults(for searchController: UISearchController) {
filterContentForSearchText(searchController.searchBar.text!)
}
}
And code of the tableview cell
import UIKit
class SuraSearchCell: UITableViewCell {
#IBOutlet weak var itemTitle: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func configureCell(item: Reciter) {
itemTitle.text = item.name
}
}
cell.textLabel is default UITableViewCell property. you just need to set value to your customCell itemTitle label.
Replace cell.textLabel!.text = candy.name with cell. itemTitle!.text = candy.name like below.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "SuraSearchCell", for: indexPath) as? SuraSearchCell {
let candy: Reciter
if isFiltering() {
candy = filteredReciters[indexPath.row]
} else {
candy = reciters[indexPath.row]
}
cell. itemTitle!.text = candy.name
//OR
cell.configureCell(candy) // IF your candy is of Reciter type
return cell
}
return UITableViewCell()
}
There may be a mistake with reuse identifier name. Match the name with the used one in the code.
Let update cellForRowAtIndex as below
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "SuraSearchCell", for: indexPath) as? SuraSearchCell {
let candy: Reciter
if isFiltering() {
candy = filteredReciters[indexPath.row]
} else {
candy = reciters[indexPath.row]
}
cell.configureCell(candy)
return cell
}
return UITableViewCell()
}
I have had a look but cannot find a suitable answer.
I have a tableview populated with the names of drugs. The drugs have been entered as they have been encountered from text into Xcode as shown below.
class MasterViewController: UITableViewController {
// MARK: - Properties
var detailViewController: DetailViewController? = nil
var drugs = [Drug]()
var filtereddrugs = [Drug]()
let searchController = UISearchController(searchResultsController: nil)
// MARK: - View Setup
override func viewDidLoad() {
super.viewDidLoad()
// Setup the Search Controller
searchController.searchResultsUpdater = self
searchController.searchBar.delegate = self
definesPresentationContext = true
searchController.dimsBackgroundDuringPresentation = false
// Setup the Scope Bar
searchController.searchBar.scopeButtonTitles = ["All", "Green", "Blue", "Amber", "Red", "Black"]
tableView.tableHeaderView = searchController.searchBar
drugs = [
Drug(category:"Green", name:"Magnesium Trisilicate"),
Drug(category:"Green", name:"Co-magaldrox (Mucogel)"),
Drug(category:"Green", name: "Gastrocote"),
Drug(category:"Green", name:"Infant Gaviscon"),
Drug(category:"Green", name:"Peptac"),
Drug(category:"Green", name:"Mebeverine"),
Drug(category:"Green", name:"Fybogel Mebeverine"),
Drug(category:"Black", name:"Peppermint oil")]
if let splitViewController = splitViewController {
let controllers = splitViewController.viewControllers
detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController
}
}
override func viewWillAppear(_ animated: Bool) {
clearsSelectionOnViewWillAppear = splitViewController!.isCollapsed
super.viewWillAppear(animated)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// MARK: - Table View
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searchController.isActive && searchController.searchBar.text != "" {
return filtereddrugs.count
}
return drugs.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let drug: Drug
if searchController.isActive && searchController.searchBar.text != "" {
drug = filtereddrugs[(indexPath as NSIndexPath).row]
} else {
drug = drugs[(indexPath as NSIndexPath).row]
}
cell.textLabel!.text = drug.name
cell.detailTextLabel!.text = drug.category
return cell
}
func filterContentForSearchText(_ searchText: String, scope: String = "All") {
filtereddrugs = drugs.filter({( drug : Drug) -> Bool in
let categoryMatch = (scope == "All") || (drug.category == scope)
return categoryMatch && drug.name.lowercased().contains(searchText.lowercased())
})
tableView.reloadData()
}
// MARK: - Segues
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showDetail" {
if let indexPath = tableView.indexPathForSelectedRow {
let drug: Drug
if searchController.isActive && searchController.searchBar.text != "" {
drug = filtereddrugs[(indexPath as NSIndexPath).row]
} else {
drug = drugs[(indexPath as NSIndexPath).row]
}
let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController
controller.detailDrug = drug
controller.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem
controller.navigationItem.leftItemsSupplementBackButton = true
}
}
}
}
extension MasterViewController: UISearchBarDelegate {
// MARK: - UISearchBar Delegate
func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
filterContentForSearchText(searchBar.text!, scope: searchBar.scopeButtonTitles![selectedScope])
}
}
extension MasterViewController: UISearchResultsUpdating {
// MARK: - UISearchResultsUpdating Delegate
func updateSearchResults(for searchController: UISearchController) {
let searchBar = searchController.searchBar
let scope = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex]
filterContentForSearchText(searchController.searchBar.text!, scope: scope)
}
}
This list of drugs is not the full list, in fact in contains many many more, too many to sort manually! And over the next few weeks I will be entering more.
I don't have the time or will power to change it to appear in the table view in alphabetical order and I am wondering could a few lines of code solve the issue?
Cheers in advance,
Mark
Try adding this, it will sort drugs whenever the property is set.
var drugs = [Drug]() {
didSet {
drugs.sort { $0.name < $1.name }
}
}
What is the purpose of willSet and didSet in Swift?
What does $0 and $1 mean in Swift Closures?
I'm building an app in which one of the functions will be sorting all of the shops in the main shopping street of our town. This is why I made a table view with some shops listed inside, with a category and a name.
I sorted them alphabetically, and made a search bar for it as you can see in this video. Something goes wrong with the navigation though, it works when not using the search bar, but it disappears when using it.
Can anybody help me with this? Thanks in advance! The code for the main view controller (which contains the complete navigation, since nothing about it's done in the storyboard) is mentioned below:
import UIKit
class MasterTableViewController: UITableViewController {
//winkels filteren
var filteredWinkels = [Winkel]()
// MARK: - Properties
var detailViewController: DetailViewController? = nil
var winkels = [Winkel]()
// MARK: - View Setup
override func viewDidLoad() {
super.viewDidLoad()
winkels = [
Winkel(category:"Literature", name:"Standaard"),
Winkel(category:"Literature", name:"Acco"),
Winkel(category:"Clothing", name:"H&M"),
Winkel(category:"Clothing", name:"C&A"),
Winkel(category:"Clothing", name:"Patio"),
Winkel(category:"Restaurants", name:"De 46"),
Winkel(category:"Cafés", name:"'t Hoekske"),
Winkel(category:"Supermarkets", name:"Carrefour"),
Winkel(category:"Supermarkets", name:"Colruyt"),
Winkel(category:"Supermarkets", name:"Blokker"),
Winkel(category:"Lingerie", name:"Hunkemoller")
]
//alfabetisch sorteren
winkels.sortInPlace({ $0.name < $1.name })
if let splitViewController = splitViewController {
let controllers = splitViewController.viewControllers
detailViewController = (controllers[controllers.count - 1] as! UINavigationController).topViewController as? DetailViewController
}
//searchController aanmaken
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
definesPresentationContext = true
tableView.tableHeaderView = searchController.searchBar
//searchButtons aanmaken
searchController.searchBar.scopeButtonTitles = ["All", "Clothing", "Supermarkets", "Literature"]
searchController.searchBar.delegate = self
self.tableView.reloadData()
}
override func viewWillAppear(animated: Bool) {
clearsSelectionOnViewWillAppear = splitViewController!.collapsed
super.viewWillAppear(animated)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// MARK: - Table View
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
//aantallen tellen
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searchController.active && searchController.searchBar.text != "" {
return filteredWinkels.count
}
return winkels.count
}
//naam cel aanpassen en checken
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
let winkel: Winkel
if searchController.active && searchController.searchBar.text != "" {
winkel = filteredWinkels[indexPath.row]
} else {
winkel = winkels[indexPath.row]
}
if winkel.name .containsString("Hunkemoller") {
cell.textLabel!.text = "Hunkemöller"
} else {
cell.textLabel!.text = winkel.name
}
cell.detailTextLabel?.text = winkel.category
return cell
}
// Segues voorbereiden
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showDetail" {
if let indexPath = tableView.indexPathForSelectedRow {
let winkel: Winkel
if searchController.active && searchController.searchBar.text != "" {
winkel = filteredWinkels[indexPath.row]
} else {
winkel = winkels[indexPath.row]
}
let controller = (segue.destinationViewController as! UINavigationController).topViewController as! DetailViewController
controller.detailWinkel = winkel
controller.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem()
controller.navigationItem.leftItemsSupplementBackButton = true
}
}
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
performSegueWithIdentifier("showDetail", sender: self)
}
//searchcontroller aanmaken
let searchController = UISearchController(searchResultsController: nil)
//scopebar maken
func filterContentForSearchText(searchText: String, scope: String = "All") {
filteredWinkels = winkels.filter { winkel in
let categoryMatch = (scope == "All") || (winkel.category == scope)
return categoryMatch && winkel.name.lowercaseString.containsString(searchText.lowercaseString)
}
tableView.reloadData()
}
}
// updaten
extension MasterTableViewController: UISearchResultsUpdating {
func updateSearchResultsForSearchController(searchController: UISearchController) {
let searchBar = searchController.searchBar
let scope = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex]
filterContentForSearchText(searchController.searchBar.text!, scope: scope)
}
}
extension MasterTableViewController: UISearchBarDelegate {
func searchBar(searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
filterContentForSearchText(searchBar.text!, scope: searchBar.scopeButtonTitles![selectedScope])
}
}
UISearchController has a property named hidesNavigationBarDuringPresentation, default is YES. I don't make sure if it is the root cause.
You can implement - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath of UITableViewDelegate, use self.navigationController.pushViewController to push your DetailViewController instead of using segue
You can set your navigation bar status of destination view controller in your prepareForSegue: method:
let controller = (segue.destinationViewController as! UINavigationController).topViewController as! DetailViewController
controller.detailWinkel = winkel
controller.navigationBarHidden = true
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)
}
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.