Show search bar with action (bar item) - ios

I have a problem with search bar. I need to create a table view with a search button in the right corner, and when I click on it, it should show the search bar.
My code is here:
// Search controller
searchController = ({
let controller = UISearchController(searchResultsController: nil)
controller.delegate = self
controller.searchBar.delegate = self
controller.searchResultsUpdater = self
controller.dimsBackgroundDuringPresentation = false
controller.hidesNavigationBarDuringPresentation = true
controller.searchBar.sizeToFit()
return controller
})()
And here is action:
// Search action
#IBAction func search(sender: UIBarButtonItem) {
print("Open search")
searchController.active = true
if searchController.searchBar.isFirstResponder() == false {
searchController.searchBar.becomeFirstResponder()
}
}
When I click on the button, nothing happens (only prints text in console), and what I want is in the image below:

Your class needs to conform to a UISearchBarDelegate, I'm not sure if you've done that already. Also make sure you present the search view
From Apple's Docs:
The UISearchBarDelegate protocol defines the optional methods you implement to make a UISearchBar control functional. A UISearchBar object provides the user interface for a search field on a bar, but it’s the application’s responsibility to implement the actions when buttons are tapped. At a minimum, the delegate needs to perform the actual search when text is entered in the text field.
Here's a sample from my app
#IBAction func searchAction(sender: UIBarButtonItem) {
// Create the search controller and specify that it should present its results in this same view
searchController = UISearchController(searchResultsController: nil)
// Set any properties (in this case, don't hide the nav bar and don't show the emoji keyboard option)
searchController.hidesNavigationBarDuringPresentation = false
searchController.searchBar.keyboardType = UIKeyboardType.ASCIICapable
// Make this class the delegate and present the search
self.searchController.searchBar.delegate = self
presentViewController(searchController, animated: true, completion: nil)
}

Old question, but want to add a new answer (maybe things changed since the original answer from 2016).
Simply call this on the view controller, assuming you already set up the search controller. No need to conform to UISearchBarDelegate:
Swift 5
present(searchController, animated: true, completion: nil)

Related

How to implement a SearchController with a SearchResultsController

Hello I am trying to implement a SearchController into my application however, my application has different tabs in which I would like them to see the search functionality. I have added a button to the NavBar and each of these tabs has a main controller view which includes this code. Unfortunately when I try to search for something the table view does not display with the results. Thank you for your help! Please find the code below:
MainController:
// set up search:
func setUpSearch(){
self.searchDataSource = DataTableViewController() // UIViewController, contains all functions for tableview plus outlet of tableview
self.searchController = UISearchController.init(searchResultsController: searchDataSource)
self.searchController?.searchBar.delegate = self
self.searchController?.searchBar.showsCancelButton = true
self.searchController?.searchBar.placeholder = "Search for people or places"
}
// user clicked on search button:
func searchButtonClicked(){
self.searchController?.isActive = true
self.searchController?.searchBar.becomeFirstResponder()
if let controller = self.searchController {
present(controller, animated: true, completion: nil)
}
}

Navbar dissapears when view is displayed from segue

I have a TableViewController that has an embedded NavigationController. There is also a ViewController to add new locations to the tableview.
This shows the relevant section of the Storyboard
When the user clicks a choose location there is a segue action through the NavigationController to the LocationChoiceTableViewController... a shortened version of the display is...
As you can see my navbar is showing with two buttons to add or edit the list. If a user clicks Add the segue action takes them to the AddLocationViewController...
The user adds details of the new location and clicks Add which has a segue action back to the LocationChoiceTableViewController passing back the values entered as a single concatenated string (newLocationtoPass)
The viewDidLoad in LocationChoiceTableViewController class has....
override func viewDidLoad() {
super.viewDidLoad()
self.resultsController.tableView.dataSource = self
self.resultsController.tableView.delegate = self
if let savedLocations = defaults.objectForKey("locations") as? NSData {
locations = NSKeyedUnarchiver.unarchiveObjectWithData(savedLocations) as![String]
}
if newLocationtoPass != nil {
// we have a new location passed via segue from AddNewLocationViewController
//add new location to locations array and sort
insertSorted(&locations, newItem: newLocationtoPass)
// save location array to NSUserDefaults
saveLocationArray()
}
self.navigationController?.setNavigationBarHidden(false, animated: true)
self.navigationItem.leftBarButtonItem = self.editButtonItem()
self.searchController = UISearchController(searchResultsController: self.resultsController)
self.tableView.tableHeaderView = self.searchController.searchBar
self.searchController.searchResultsUpdater = self
self.searchController.dimsBackgroundDuringPresentation = false
definesPresentationContext = true
}
Which if newLocationtoPass is not null will insert the value into the array (in the correct sorted position) and save the array to NSUserDefaults... All this works as shown in the screenshot below...
My problem is that I have lost my navbar with the edit/add buttons. I added the line self.navigationController?.setNavigationBarHidden(false, animated: true) but the navbar does not show when returning from AddLocationViewController.
Any help in fixing this would be appreciated.
try to write self.navigationController?.setNavigationBarHidden(false, animated: true) in viewWillAppear .. this may help you..
Fixed... I changed my Storyboard so that the segue actions from the Cancel and Add buttons on the AddLocationViewController went to the NavigationController and not the LocationChoiceTreeViewController.

ios 9 Search Cancel undoes action

I have two buttons on top of a map. If you tap the search button the buttons animate to switch places; which is what i want. However if you cancel the search I would like the buttons to switch back. I tried this
self.searchDisplayController.active = false
(which i know is depreciated)
inside of an if statement and it did not work
I was wondering what code I could put inside an if statement would do what I want to do.
Here is the search button code
#IBAction func showSearchBar(sender: AnyObject) {
searchController = UISearchController(searchResultsController: nil)
searchController.hidesNavigationBarDuringPresentation = false
self.searchController.searchBar.delegate = self
presentViewController(searchController, animated: true, completion: nil)
setButtonPosition("buyer")
}
the last line
setButtonPosition("buyer")
is what switches the button position
Thanks

Make UISearchBar dismiss like Music App

Notice how the searchBar magnifying glass and placeholder text both shift over on dismissal:
Is there any way I could dismiss this search bar without the text and icon moving over? See the animation of the Music app for the animation I am trying to achieve.
I have a UISeachBar that gets presented when the search button is clicked in a nav bar.
#IBAction func searchButtonPressed(sender: AnyObject) {
searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.searchBar.delegate = self
searchController.hidesNavigationBarDuringPresentation = false
searchController.dimsBackgroundDuringPresentation = false
presentViewController(searchController, animated: true, completion: nil)
}
Now when the cancel button is pressed, I want the whole view to move up without seeing the SearchBar icon and placeholder text slide to the center of the searchBar as the view moves up off screen.
I know there is the method searchBarCancelButtonClicked(searchBar:), but this seems to automatically dismiss the SearchBar and I don't know how to control that.
How can I make the SearchBar dismiss like the one in the Music app?
EDIT: Here is the only delegate method I am using:
func updateSearchResultsForSearchController(searchController: UISearchController) {
masterFilter.removeAll()
filterContentForSearchText(searchController.searchBar.text!)
tableView.reloadData()
}
This is how I have achieved this. It is simple and easy.
extension UIViewController {
func setNavigationBarItem() {
let searchaButton = UIButton.init(frame: CGRectMake(0, 0, 30, 30))
searchaButton.setBackgroundImage(UIImage(named: "search.png"), forState: UIControlState.Normal)
searchaButton.addTarget(self, action: #selector(self.searchPressed), forControlEvents: UIControlEvents.TouchUpInside)
let rightButton: UIBarButtonItem = UIBarButtonItem.init(customView: searchaButton)
navigationItem.rightBarButtonItem = rightButton
}
public func searchPressed(){
var searchController: UISearchController!
// Create the search results view controller and use it for the UISearchController.
let searchResultsController = storyboard!.instantiateViewControllerWithIdentifier("SearchResultController") as! SearchResultsViewController
// Create the search controller and make it perform the results updating.
searchController = UISearchController(searchResultsController: searchResultsController)
searchController.searchResultsUpdater = searchResultsController
searchController.hidesNavigationBarDuringPresentation = false
// Present the view controller.
presentViewController(searchController, animated: true, completion: nil)
}
}
Note:
This code is for old swift version.
I hope this will help you.
The searchBar expands to the right because the search is being cancelled, and the cancel button is disappearing.
Instead of canceling the search and triggering that animation, simply explicitly dismiss the search controller.
You can do this by setting
searchController.active = false
To make this animation work, you'll need to understand custom UIViewController transitions. Within the UISearchBarDelegate method -searchBarCancelButtonClicked(searchBar:), you'll need to do a few things:
Hide the UINavigationBar on the UISearchController dismissal
Animate the UITableView to the bottom of the frame and fade out.
If you're presenting search modally, ensure that you're setting the modalPresentationStyle to UIModalPresentationCurrentContext.

UISearchController background color with no text

I created a table view with the following code:
searchController = UISearchController(searchResultsController: self)
presentViewController(searchController, animated: true, completion: nil)
In the viewDidInitialize method. When text is entered, the table view displays as expected:
If no text is entered into the search field, I cannot see the table view. Is there a trick to showing the table view in this state or is there any other way to customize the background? I've tried setting dimsBackgroundDuringPresentation to false but that did not work.
Works if you pass nil instead of self
searchController = UISearchController(searchResultsController: nil)

Resources