Search Bar Glitch - ios

The problem:
Instead of adding a search bar(with a search and results controller) to a table view controller, I have added it to a regular view controller's navigation bar. At first everything seems fine, but when I click on the search bar the screen turns gray.
This is my code:
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UISearchResultsUpdating, UISearchBarDelegate{
var schools = ["Saratoga", "Fremont", "Argonaut", "Redwood", "Foothill", "Miller", "Rolling Hills"].sorted()
var filteredSchools = ["Saratoga", "Fremont", "Argonaut", "Redwood", "Foothill", "Miller", "Rolling Hills"].sorted()
var searchController: UISearchController!
var resultsController: UITableViewController!
override func viewDidLoad() {
super.viewDidLoad()
resultsController = UITableViewController()
searchController = UISearchController(searchResultsController: resultsController)
resultsController.tableView.delegate = self
resultsController.tableView.dataSource = self
searchController.searchResultsUpdater = self
self.view.addSubview(searchController.searchBar)
navigationItem.leftBarButtonItem = UIBarButtonItem(customView: searchController.searchBar)
}
func updateSearchResults(for searchController: UISearchController) {
let currText = searchController.searchBar.text ?? ""
filteredSchools = schools.filter({ (school) -> Bool in
if school.contains(currText){
return true
}
return false
})
resultsController.tableView.reloadData()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredSchools.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = filteredSchools[indexPath.row]
return cell
}
}

Add these lines in viewDidLoad:
resultsController.tableView.backgroundColor = UIColor.clear
searchController.hidesNavigationBarDuringPresentation = false
Your Navigation Bar is hiding that's all.
If you don't want the gray tint:
searchController.dimsBackgroundDuringPresentation = false

Related

updateSearchResults function is not being called when searchBar is touched

The updateSearchResults function isn't getting called in my view table controller view for some reason and I don't know why? I've seen this answer but it's nothing similar to mine and I don't want to use the textDidChange function.
I have this view SearchViewController where it has a search bar at the top and it will have a collection view below it. (Making instagrams explore page). Once the search bar has been tapped, it should display view SearchTableViewController which shows the results of the search query in a table view.
This is my code:
SearchViewController (the main view):
import UIKit
class SearchViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let storyboard = UIStoryboard(name: "Main", bundle: nil)
guard let searchResultsViewController = storyboard.instantiateViewController(withIdentifier: "SearchResultsViewController") as? SearchTableViewController else { return}
let searchController = UISearchController(searchResultsController: searchResultsViewController)
searchController.searchResultsUpdater = searchResultsViewController
view.addSubview(searchController.searchBar)
definesPresentationContext = true
}
}
SearchTableViewController (the view that gets displayed with the results):
import UIKit
import Firebase
class SearchTableViewController: UIViewController {
let languages = ["Mandarin Chinese", "English", "Hindustani", "Spanish", "Arabic", "Malay", "Russian", "Bengali", "Portuguese", "French", "Hausa", "Punjabi", "German", "Japanese", "Persian", "Swahili", "Telugu", "Javanese", "Wu Chinese", "Korean"]
var searchResults: [String] = []
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
}
}
extension SearchTableViewController: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
print("typing")
guard let searchText = searchController.searchBar.text else { return }
searchResults = languages.filter { $0.contains(searchText) }
tableView.reloadData()
}
}
extension SearchTableViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return searchResults.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "searchCell", for: indexPath)
let language = searchResults[indexPath.row]
cell.textLabel?.text = language
return cell
}
}
the updateSearchResults in the extension SearchTableViewController: UISearchResultsUpdating isn't being called which I think is the cause of the table view with the search results not loading the search query data?
I forgot to add the assignment to the navigation controller too. Even if you're showing the search results on another screen you still need to add it:
navigationItem.searchController = theSearchControllerYouInstantiated

I can not solve the error "coding classification not key value coding-compliant for the key"

It is a question.
This class is not key value code-compliant for the key error is given.
However, I am not sure which part is wrong. This error appears at cellForRowAt.
Thank you for your answer.
If you want it, I can also show the code of ContentTableViewCell, so please call out.
import UIKit
class SearchViewController: UIViewController, UISearchResultsUpdating {
#IBOutlet weak var tableview: UITableView!
var songs = [
"裁量権を持って、若者向けカレンダーアプリ開発をしたいiOSエンジニア募集!",
"自信を持って、応援出来るエンジニアを募集!"
]
var searchSongs = [String]()
func updateSearchResults(for searchController: UISearchController) {
let searchString = searchController.searchBar.text!
searchSongs = songs.filter {(name) -> Bool in
return name.contains(searchString)
}
tableview.reloadData()
}
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.prefersLargeTitles = true
let searchController = UISearchController(searchResultsController:nil)
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
navigationItem.searchController = searchController
definesPresentationContext = true
delegate()
}
}
extension searchViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if navigationItem.searchController?.isActive == true {
return searchSongs.count
} else {
return songs.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableview.dequeueReusableCell(withIdentifier: "ContentTableViewCell", for: indexPath) as! ContentTableViewCell
if navigationItem.searchController?.isActive == true {
cell.commonInit(content: searchSongs[indexPath.row])
} else {
cell.commonInit(content: songs[indexPath.row])
}
return cell
}
func delegate() {
tableview.delegate = self
tableview.dataSource = self
let nibName = UINib(nibName: "ContentTableViewCell", bundle: nil)
self.tableview.register(nibName, forCellReuseIdentifier: "ContentTableViewCell")
}
}
Check in your Storyboard. I think any outlet is not connected properly.
Check is there any yellow warning triangle in your storyboard on which screen this error is coming. If you found any, remove and connect the outlet again.

How to implement search bar like this?

I would like to add a search bar above my collection view and when press it will show like the video showing .https://www.youtube.com/watch?v=mgS2Pzy5eJk .Thanks.
You can directly use iOS default UISearchDisplayController as following tutorial:
UISearchDisplayController Tutorial
Read this tutorial and try it..
Hope it helps...
When the user click the searchBar:
remove or hide the NavigationBar
Adjust the auto layout constraint of search Bar accordingly.
Add animation as you want
Do these thing in func searchBarTextShouldBeginEditing(searchBar: UISearchBar)
func searchBarTextShouldBeginEditing(searchBar: UISearchBar) {
//remove or hide the NavigationBar
//update auto layout constraint
UIView.animateWithduration(0.3) {
self.view.layoutIfNeeded()
}
return true
}
class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource,UISearchResultsUpdating {
#IBOutlet weak var tableview: UITableView!
let unfilteredNFLTeams = ["Bengals", "Ravens", "Browns", "Steelers", "Bears", "Lions", "Packers", "Vikings",
"Texans", "Colts", "Jaguars", "Titans", "Falcons", "Panthers", "Saints", "Buccaneers",
"Bills", "Dolphins", "Patriots", "Jets", "Cowboys", "Giants", "Eagles", "Redskins",
"Broncos", "Chiefs", "Raiders", "Chargers", "Cardinals", "Rams", "49ers", "Seahawks"].sorted()
var filteredNFLTeams: [String]?
let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
filteredNFLTeams = unfilteredNFLTeams
searchController.searchResultsUpdater = self
searchController.hidesNavigationBarDuringPresentation = false
searchController.dimsBackgroundDuringPresentation = false
tableview.tableHeaderView = searchController.searchBar
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard let nflTeams = filteredNFLTeams else {
return 0
}
return nflTeams.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "nandhu", for: indexPath)
if let nflTeams = filteredNFLTeams {
let team = nflTeams[indexPath.row]
cell.textLabel!.text = team
}
return cell
}
func updateSearchResults(for searchController: UISearchController) {
if let searchText = searchController.searchBar.text, !searchText.isEmpty {
filteredNFLTeams = unfilteredNFLTeams.filter { team in
return team.lowercased().contains(searchText.lowercased())
}
} else {
filteredNFLTeams = unfilteredNFLTeams
}
tableview.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

Hide Cancel Button on UISearchController swift 2.0

theres any way to hide the cancel button on UISearchController?
The other behaviour i would like to know if its possible, is when the user press the Cancel Button, to set the text on the UISearchBar.
Thanks
Using seachController.searchBar.setShowsCancelButton(false, animated:false) still seems to not do it for this.
Try adding the UISearchBarDelegate to your controller and assign the searchBar's delegate to self. Then you can use the searchBarShouldBeginEditing to edit its visibility.
import UIKit
class TableViewController: UITableViewController, UISearchBarDelegate {
var searchController: UISearchController!
let menuItems: [String] = ["Row 1", "Row 2", "Row 3"]
override func viewDidLoad() {
super.viewDidLoad()
let searchResultsController = storyboard!.instantiateViewControllerWithIdentifier("SearchResultsViewControllerStoryboardIdentifier") as! SearchResultsTableViewController
searchController = UISearchController(searchResultsController: searchResultsController)
searchController.hidesNavigationBarDuringPresentation = false
searchController.searchBar.delegate = self
}
#IBAction func searchButtonPressed(sender: UIBarButtonItem) {
presentViewController(searchController, animated: true, completion: nil)
}
func searchBarShouldBeginEditing(searchBar: UISearchBar) -> Bool {
searchController.searchBar.setShowsCancelButton(false, animated: true)
return true
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return menuItems.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
cell.textLabel?.text = self.menuItems[indexPath.row]
return cell
}
}

headerview from previous view takes up space in UISearchController search results

I have a simple tableView, DailyAttendanceController, with a searchbar. Searchbar was added in its viewDidLoad. View TableView here.
import UIKit
class OldCellsTableViewController: UITableViewController {
let data = ["A", "B", "C"]
var searchController:UISearchController!
let resultsController = SearchResultsUpdater()
override func viewDidLoad() {
super.viewDidLoad()
resultsController.data = data
searchController = UISearchController(searchResultsController: resultsController)
let searchBar = self.searchController.searchBar
searchBar.scopeButtonTitles = ["All", "Short", "Long"]
searchBar.placeholder = "Search for a student"
searchBar.sizeToFit()
self.tableView.tableHeaderView = searchBar
self.searchController.searchResultsUpdater = resultsController
}
// MARK: - Table view data source
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = UITableViewCell()
let info = data[indexPath.row]
cell.textLabel?.text = info
return cell
}
}
I then created another class, SearchResultsController, to handle the search. Searching works fine, but space is allocated for DailyAttendanceController's header. View SearchResultsController here
How do I remove this?
Code for my SearchResultsController:
import UIKit
import CoreData
class SearchResultsController: UITableViewController, UISearchResultsUpdating {
var data:[String] = []
var filteredData:[String] = []
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// MARK: - Table view data source
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredData.count
}
func updateSearchResultsForSearchController(searchController: UISearchController) {
filteredData.removeAll(keepCapacity: true)
let searchString = searchController.searchBar.text
for info in data {
if (info.uppercaseString.rangeOfString(searchString.uppercaseString) != nil) {
filteredData.append(info)
}
}
tableView.reloadData()
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = filteredData[indexPath.row]
return cell
}
}

Resources