adding searchBar to navigationBar in swift - ios

i'm trying to add a searchBar to the navigationBar. i've researched a bit and this is what i've done so far:
The problem is nothing appear to the navigationBar using this code.
searchBar = UISearchBar(frame: CGRectMake(0, 0, 320, 44))
searchBar?.delegate = self
searchBar?.showsCancelButton = true
searchController = UISearchDisplayController()
searchController?.delegate = self
searchController?.searchResultsDelegate = self
searchController?.displaysSearchBarInNavigationBar = true

Try this code that worked for me:
lazy var searchBars:UISearchBar = UISearchBar(frame: CGRectMake(0, 0, 200, 20))
override func viewDidLoad() {
super.viewDidLoad()
var leftNavBarButton = UIBarButtonItem(customView: searchBars)
self.navigationItem.leftBarButtonItem = leftNavBarButton
}

Try this
lazy var searchBar = UISearchBar(frame: .zero)
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.titleView = searchBar}

You can use this
private let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
self.navigationItem.searchController = searchController
self.navigationItem.hidesSearchBarWhenScrolling = false
}

Related

How to fix UISearchController search bar resizing when focused?

I am trying to implement a UISearchController with a UITableView inside of a small popup screen like this:
Image displaying a popup with a UITableView and UISearchController.
However, when the search bar is focused, it moves up and becomes wider, as shown here:
Image displaying a glitched search bar.
I have found one other post about this issue here, but the accepted solution did not seem to fix the problem.
For reference, I am using a modal segue displaying over full screen. There is a content view in which the tableView and titleLabel are subviewed. Here is the relevant code for the popup view controller.
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var titleLabel: UILabel!
var items = ["Test", "oewrghp", "wopqet", "vbsjadsf", "rweoghp", "bmwehth", "pqeojnh"]
var filteredItems = [String]()
let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(dismissTapGesture(gesture:)))
view.addGestureRecognizer(tapGesture)
view.backgroundColor = UIColor(displayP3Red: 0, green: 0, blue: 0, alpha: 0.3)
searchController.searchResultsUpdater = self
searchController.hidesNavigationBarDuringPresentation = false
searchController.searchBar.barTintColor = .white
searchController.searchBar.backgroundColor = .clear
searchController.searchBar.delegate = self
searchController.obscuresBackgroundDuringPresentation = false
titleLabel.text = "Search"
tableView.tableHeaderView = searchController.searchBar
tableView.delegate = self
tableView.dataSource = self
tableView.reloadData()
tableView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:))))
// Do any additional setup after loading the view.
}
Use a UISearchBar instead of a UISearchController
Something like:
let searchBar = UISearchBar(frame: CGRect(x: 0, y: 0, width: tableView.frame.size.width, height: 44))
Hope this helps someone!

How to remove navigation bar from view controller

SearchViewController viewDidLoad has the following functionality
override func viewDidLoad() {
super.viewDidLoad()
self.cache = NSCache()
let path = "books";
self.ref = Database.database().reference().child(path);
tableViewBooks.dataSource = self
tableViewBooks.delegate = self
tableViewBooks.register(BookDetailTableViewCell.self, forCellReuseIdentifier: "book")
// Uncomment the following line to preserve selection between presentations
self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Search"
searchController.searchBar.searchBarStyle = UISearchBar.Style.prominent
searchController.searchBar.isTranslucent = false
let searchBarView = UIView(frame: CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(UIScreen.main.bounds.size.width), height: CGFloat(45)))
let view = UIView();
view.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width , height: 54)
let searchBar = searchController.searchBar
searchBar.backgroundColor = UIColor.white
searchBar.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width , height: 44)
searchBar.searchBarStyle = UISearchBar.Style.prominent
searchBar.placeholder = " Search book title..."
searchBar.sizeToFit()
view.backgroundColor = UIColor.white
searchBar.isTranslucent = false
searchBarView.addSubview(searchBar)
view.addSubview(searchBarView)
tableView.tableHeaderView = view
definesPresentationContext = true
tableView.separatorStyle = .none
}
When someone clicks on a row in the tableview in that view controller, they get sent to DetailController
tableRowData = filteredBooks[indexPath.row]
self.performSegue(withIdentifier: "toDetail", sender: nil)
DetailControler has a navigation bar that I can't seem to remove. I tried to add the following code to viewWillAppear, but it made no difference. What can I do?
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.setNavigationBarHidden(true, animated: false)
self.navigationController?.setNavigationBarHidden(true, animated: true)
self.navigationController?.navigationBar.isHidden = true
self.navigationController?.isNavigationBarHidden = true
refresh()
}
I have tried your code and found that if you set hidesNavigationBarDuringPresentation to false, the DetailController's navigationBar will be hidden correctly. Here is my code
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Search"
searchController.searchBar.searchBarStyle = UISearchBar.Style.prominent
searchController.searchBar.isTranslucent = false
searchController.hidesNavigationBarDuringPresentation = false

SearchController SearchBar width issue iOS11

I am trying to add SearchController SearchBar programmatically in one of UIVIew as subView but initially it working properly up to iOS 10 but getting issue in iOS11 width getting increased get displaced.
I tried all possible solutions, Created Custom class init SearchBar frame with CGRect.zero & even hide cancel button. Still i does not understanding where I am doing wrong.
Initial Screen:
Issue is here when i clicked on SearchBar
Irony is its not working even i am trying to reset frame width to 100.0f by calling method viewWillLayoutSubviews from searchBarShouldBeginEditing
func setUpSearchBar(){
self.automaticallyAdjustsScrollViewInsets = false
resultsViewController = GMSAutocompleteResultsViewController()
resultsViewController?.delegate = self as GMSAutocompleteResultsViewControllerDelegate
searchController = CustomSearchController(searchResultsController: resultsViewController)
searchController?.searchResultsUpdater = resultsViewController
//resultsViewController?.view.frame = searchAndButtonView.bounds
//let subView = UIView(frame: CGRect(x: 0, y: 65.0, width: 350.0, height: 45.0))
searchController?.searchBar.frame = CGRect(x: 0, y: 0, width: searchView.frame.size.width, height: searchView.frame.size.height)
searchController?.searchBar.delegate = self
searchView.addSubview((searchController?.searchBar)!)
searchView.translatesAutoresizingMaskIntoConstraints = false
searchController?.searchBar.sizeToFit()
searchController?.hidesNavigationBarDuringPresentation = false
searchController?.searchBar.searchBarStyle = .minimal
definesPresentationContext = false
self.extendedLayoutIncludesOpaqueBars = true
self.edgesForExtendedLayout = .top
}
CustomSearchController.swift
class CustomSearchController: UISearchController,UISearchBarDelegate{
let noCancelButtonSearchBar = NoCancelButtonSearchBar()
lazy var _searchBar: NoCancelButtonSearchBar = {
[unowned self] in
let customSearchBar = NoCancelButtonSearchBar(frame: CGRect.zero)
return customSearchBar
}()
override var searchBar: UISearchBar {
get {
return _searchBar
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// 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.
}
*/
}
class NoCancelButtonSearchBar: UISearchBar {
override func setShowsCancelButton(_ showsCancelButton: Bool, animated: Bool) { /*
void */ }
}
After lot of attempts i resolved issue by following way,
I removed customised CustomSearchController class & used simple UISearchController .
func setUpSearchBar(){
self.automaticallyAdjustsScrollViewInsets = false
resultsViewController = GMSAutocompleteResultsViewController()
resultsViewController?.delegate = self as GMSAutocompleteResultsViewControllerDelegate
searchController = UISearchController(searchResultsController: resultsViewController)
searchController?.searchResultsUpdater = resultsViewController
searchController?.searchBar.frame = CGRect(x: 0, y: 0, width: searchView.frame.size.width, height: searchView.frame.size.height)
let searchBarContainer = SearchBarContainerView(customSearchBar: searchController?.searchBar)
searchBarContainer.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: 44)
searchController?.searchBar.delegate = self
searchView.addSubview(searchBarContainer)
searchView.translatesAutoresizingMaskIntoConstraints = false
searchController?.searchBar.sizeToFit()
searchController?.hidesNavigationBarDuringPresentation = false
searchController?.searchBar.searchBarStyle = .minimal
definesPresentationContext = false
self.extendedLayoutIncludesOpaqueBars = true
self.edgesForExtendedLayout = .top
}
And add SearchBarContainerView class,
class SearchBarContainerView: UIView {
let searchBar: UISearchBar
init(customSearchBar: UISearchBar) {
searchBar = customSearchBar
super.init(frame: CGRect.zero)
addSubview(searchBar)
}
override convenience init(frame: CGRect) {
self.init(customSearchBar: UISearchBar())
self.frame = frame
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
searchBar.frame = bounds
}
}
Following is working screenshot:
Try this code. it worked for me. I was also facing the same issue.
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
searchbar.invalidateIntrinsicContentSize()
}

How to add SearchController.searchBar under navigationBar (UITableView) swift

I try to add SearchController.searchBar under navigation bar.
override func viewDidLoad() {
super.viewDidLoad()
searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.searchBar.sizeToFit()
searchController.hidesNavigationBarDuringPresentation = false
searchController.delegate = self
searchController.dimsBackgroundDuringPresentation = false //
searchController.searchBar.delegate = self
let SearchFrame = CGRectMake(0,(self.navigationController?.navigationBar.frame.height)!, (self.navigationController?.navigationBar.frame.width)!,searchController.searchBar.frame.height)
searchController.searchBar.frame = SearchFrame
self.navigationController?.navigationBar.addSubview(searchController.searchBar)
}
This code add a searchBar under navigationBar, but searchBar can't detect user interaction! I can't click on search text input field!! What did I do wrong?
Try this. It works for me
var SearchFrame : CGRect?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.searchBar.sizeToFit()
searchController.hidesNavigationBarDuringPresentation = false
searchController.delegate = self
searchController.dimsBackgroundDuringPresentation = false //
searchController.searchBar.delegate = self
SearchFrame = CGRectMake(0,(self.navigationController?.navigationBar.frame.height)!, (self.navigationController?.navigationBar.frame.width)!,searchController.searchBar.frame.height)
searchController.searchBar.frame = SearchFrame!
self.navigationController?.navigationBar.addSubview(searchController.searchBar)
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
var navbarFrame = self.navigationController!.navigationBar.frame
navbarFrame.size = CGSize(width: navbarFrame.width, height: navbarFrame.height + SearchFrame!.height)
self.navigationController?.navigationBar.frame = navbarFrame
}
My problem was solved!
First we need to create a XIB file with class and add two navigationBar to them!
Then need to add a IBOutlets!
Then write the code:
var TitleNavigationBar = UINavigationBar() //This need to add Title and Subtitle to NavigationBarTitleView
override func viewDidLoad() {
super.viewDidLoad()
let NavBarWithSearch = NSBundle.mainBundle().loadNibNamed("NavBarWithSearchBar", owner: self, options: nil)[0] as! NavBarWithSearchBar
self.navigationController?.navigationBar.frame = CGRectMake((self.navigationController?.navigationBar.frame.origin.x)!, 0.0, (self.navigationController?.navigationBar.frame.width)!, (self.navigationController?.navigationBar.frame.height)! + self.searchController.searchBar.frame.height)
NavBarWithSearch.frame = CGRectMake(0.0,0.0, (self.navigationController?.navigationBar.frame.width)!, (self.navigationController?.navigationBar.frame.height)!)
NavBarWithSearch.NavigationBarForSearchBar.topItem?.titleView = searchController.searchBar
TitleNavigationBar = NavBarWithSearch.CustomNavigationBar //=======This need to add Title and Subtitle to NavigationBarTitleView`
self.navigationController?.navigationBar.addSubview(NavBarWithSearch)
self.automaticallyAdjustsScrollViewInsets = false
tableView.contentInset = UIEdgeInsetsMake((self.navigationController?.navigationBar.frame.height)! + UIApplication.sharedApplication().statusBarFrame.height, 0, (self.tabBarController?.tabBar.frame.height)!, 0)
searchController.hidesNavigationBarDuringPresentation = false
}
override func viewWillAppear(animated: Bool) {
//This need to add Title and Subtitle to NavigationBarTitleView
let titleView = NSBundle.mainBundle().loadNibNamed("NavTitleView", owner: self, options: nil)[0] as! NavTitleView
titleView.TitleLabel.text = "Title"
titleView.contentMode = UIViewContentMode.ScaleAspectFit
titleView.SubtitleLabel.text = "SubTitle"
let TitleViewFrame = CGRectMake((UIScreen.mainScreen().bounds.width/2) - 80, 0, 160, 44)
titleView.frame = TitleViewFrame
TitleNavigationBar.topItem?.titleView = titleView
//========This need to add Title and Subtitle to NavigationBarTitleView
self.navigationController?.navigationBar.frame = CGRectMake((self.navigationController?.navigationBar.frame.origin.x)!, 20, (self.navigationController?.navigationBar.frame.width)!, (self.navigationController?.navigationBar.frame.height)! + self.searchController.searchBar.frame.height)
}
XIB file with Class for NavBarTitleView with subtitle should be look like
like this:
Finally i get beautiful Navigation Bar with search bar!
P.S. searchController.hidesNavigationBarDuringPresentation = true // This doesn't work because Custom navigation bar added to main navigation bar as subview!

Search Bar disappears after tap on it

Am trying to implement search nearby places using google maps. The below is the code what I have done so far
override func viewDidLoad() {
super.viewDidLoad()
//Adding Mapview
mapView = GMSMapView(frame: CGRectMake(0, 120, self.view.bounds.width, self.view.bounds.height - 120))
self.view.addSubview(mapView)
mapView.mapType = kGMSTypeNormal
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
let resultTableView = UITableView(frame: CGRectMake(10, 100, 300, 60))
self.searchResultController = UITableViewController()
self.searchResultController?.tableView = resultTableView
self.searchResultController?.tableView.dataSource = self
self.searchResultController?.tableView.delegate = self
self.searchResultController?.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
self.searchController = UISearchController(searchResultsController: self.searchResultController)
self.searchController?.searchResultsUpdater = self
self.searchController?.hidesNavigationBarDuringPresentation = true
self.searchController?.dimsBackgroundDuringPresentation = false
self.searchController?.delegate = self
self.searchController?.searchBar.frame = CGRectMake(0,70,self.view.bounds.width,40)
self.searchController?.searchBar.placeholder = "Please choose a location"
self.view.addSubview(self.searchController!.searchBar)
self.definesPresentationContext = true
}
Everything works fine, except searcg bar disappears after a single tap. But it does its function.
I found the solution for my above problem.
func willPresentSearchController(searchController: UISearchController){
self.searchResultController?.tableView.addSubview(self.searchController!.searchBar)
}
Hope it helps to others!!!
Try calling [[[self searchController] searchBar] sizeToFit]; inside layoutSubviews method. It helped me.

Resources