How do I use UISearchController in iOS 8 where the UISearchBar is in my navigation bar and has scope buttons?
You're bumping into a "design issue" where the scopeBar
is expected to be hidden when the searchController
is not active.
The scope bar buttons appear behind (underneath) the search bar since that's their location when the search bar becomes active and animates itself up into the navigation bar.
When the search is not active, a visible scope bar would take up space on the screen, distract from the content, and confuse the user (since the scope buttons have no results to filter).
Since your searchBar
is already located in the titleView, the (navigation and search) bar animation that reveals the scope bar doesn't occur.
- The easiest option is to locate the search bar below the
navigation bar, and let thesearchBar
animate up into the title
area when activated. The navigation bar will animate its height,
making room to include the scope bar that was hidden. This will all
be handled by the search controller. The second option, almost as easy, is to use a Search bar button
icon, which will animate thesearchBar
andscopeBar
down into
view over the navigation bar.- (IBAction)searchButtonClicked:(UIBarButtonItem *)__unused sender {
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.searchController.hidesNavigationBarDuringPresentation = NO;
self.searchController.dimsBackgroundDuringPresentation = NO;
self.definesPresentationContext = YES;
self.searchController.searchBar.scopeButtonTitles = @[@"Posts", @"Users", @"Subreddits"];
[self presentViewController:self.searchController animated:YES completion:nil];
}If you want the
searchBar
to remain in the titleView, an animation
to do what you want is not built in. You'll have to roll your own
code to handle the navigationBar height change and display your own
scope bar (or hook into the internals, and animate the built-inscopeBar
down and into view).If you're fortunate, someone else has written
willPresentSearchController:
code to handle the transition you want.If you want to always see a
searchBar
andscopeBar
, you'll probably have to ditch using the built-inscopeBar
, and replace it with aUISegmentedControl
which the user will always see, even when the search controller is not active.
Update:
This answer suggested subclassing UISearchController
to change its searchBar's height.
How do I set the UISearchController's searchBar to a view that isn't the tableHeaderView or navigationItem.titleview?
If you have a blank UIView that is placed above the tableview.
let's assume you have an outlet to that blank UIView called searchContainer
.
Then you can add the search bar of the UISearchController
to that view by adding the following line
searchContainer.addSubview(searchController.searchBar)
Unable to add UISearchController's search bar into navigationbar and delegate methods not getting called
Just define UISearchController
as property then everything working fine.
I have tested below in the sample project.
class ViewControllerName: UIViewController{
let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
let search = UISearchController(searchResultsController: nil)
self.navigationItem.searchController = search
self.navigationItem.searchController!.searchBar.delegate = self
self.navigationItem.searchController!.searchResultsUpdater = self
self.navigationItem.searchController?.searchBar.showsCancelButton = true
}
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
print("Called")
}
func updateSearchResults(for searchController: UISearchController) {
print("Called")
}
}
Hope it will work for you.
How is UISearchController meant to be used without UINavigationController?
You may be over-thinking this. You could perfectly well use a UISearchController without a navigation controller or a table view. The only reason people use a table view is that it's nice to have some way of displaying the search results. But UISearchController is a perfectly ordinary view controller and just does its job regardless. It really is the simplest thing in the world — that's the beauty of it. It's so simple, it can do anything with regard to search.
Here's the tiniest example I could think of. This is basically the entire code of the app:
class ViewController: UIViewController {
var sc : UISearchController?
override var prefersStatusBarHidden: Bool { true }
override func viewDidLoad() {
super.viewDidLoad()
let vc2 = ViewController2()
let sc = UISearchController(searchResultsController: vc2)
self.sc = sc
sc.searchResultsUpdater = vc2
let sb = sc.searchBar
self.view.addSubview(sb)
}
}
class ViewController2: UIViewController, UISearchResultsUpdating {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .green
}
func updateSearchResults(for searchController: UISearchController) {
guard searchController.isActive else {return}
if let t = searchController.searchBar.text, !t.isEmpty {
print("You are searching for", t)
}
}
}
That illustrates perfectly what UISearchController does, namely almost nothing. It just responds to the user tapping in the search bar by putting up a secondary view controller and signaling when the user types in the search bar. Everything else is up to you.
Related Topics
How to Do Transforms on a Calayer
How to Integrate Nsurlconnection with Uiprogressview
Swift:Missing Argument Label 'Xxx' in Call
Uisearchbar Change Placeholder Color
Generating an Unsigned IPA iOS Application
Swift - How to Get Last Taken 3 Photos from Photo Library
Behavior Differences Between Performblock: and Performblockandwait:
Error Appstore Connect:Missing Purpose String in Info.Plist File
Uipopovercontroller Dealloc Reached While Popover Is Still Visible
How to Make Both Header and Footer in Collection View with Swift
How to Check If iOS App Is in Background
How to Tell If Your Code Is Running on an iPhone or an Iphone3G
Can a Standard Accessory View Be in a Different Position Within a Uitableviewcell