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!
Related
I just started to learn how to code with Swift in Xcode, I need some help regarding the search bar. I want to add a search field bar to my navigation bar in center, and next to it i want to add two items . So far I managed to add a UISearch to my navigation bar but once I try to add items next to it, it pushes my icons above the search field.
Pressed State
Normal State
Does anyone know what to add the two menu items next to it programmatically or in the storyboard? And how to make the search field centered and a bit thinner?
My code now:
override func viewDidLoad() {
super.viewDidLoad()
let searchController = UISearchController(searchResultsController: nil)
searchController.delegate = self as? UISearchControllerDelegate
let searchBar = searchController.searchBar
searchBar.tintColor = UIColor.white
searchBar.barTintColor = UIColor.white
if let textfield = searchBar.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;
}
}
if let navigationbar = self.navigationController?.navigationBar {
navigationbar.barTintColor = UIColor.blue
}
navigationItem.searchController = searchController
navigationItem.hidesSearchBarWhenScrolling = false
}
Reddit Example
Okay, fixed it! Just used the code below. Now my next struggle is changing the background of the textfield.
//SEARCH
let searchController = UISearchController(searchResultsController: nil)
searchController.hidesNavigationBarDuringPresentation = false
searchController.dimsBackgroundDuringPresentation = false
searchController.searchBar.delegate = self as? UISearchBarDelegate
let frame = CGRect(x: 0, y: 0, width: 300, height: 44)
let titleView = UIView(frame: frame)
searchController.searchBar.backgroundImage = UIImage()
searchController.searchBar.frame = frame
titleView.addSubview(searchController.searchBar)
navigationItem.titleView = titleView
}
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
I have a main view controller, it has a fullscreen UITableView which is populated by values from Firebase and a TabBarController below. All the code for the UITableView is handled programmatically. I need to add two options: Firstly, a search bar to query the results and a filter option for the various categories to fetch from Firebase.
Here is my updated code from the ViewController:
import UIKit
import Firebase
class PostTable: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchControllerDelegate,UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
}
var tableView:UITableView!
var posts = [Post]()
var searchController : UISearchController!
override func viewDidLoad() {
super.viewDidLoad()
if Auth.auth().currentUser == nil {
switchStoryboard()
}
tableView = UITableView(frame: view.bounds, style: .plain)
view.addSubview(tableView)
let cellNib = UINib(nibName: "PostTableViewCell", bundle: nil)
tableView.register(cellNib, forCellReuseIdentifier: "postCell")
var layoutGuide:UILayoutGuide!
layoutGuide = view.safeAreaLayoutGuide
tableView.leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor).isActive = true
tableView.topAnchor.constraint(equalTo: layoutGuide.topAnchor).isActive = true
tableView.trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor).isActive = true
tableView.delegate = self
tableView.dataSource = self
tableView.tableFooterView = UIView()
tableView.reloadData()
searchController = UISearchController(searchResultsController: nil)
searchController.delegate = self
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false // displays tableview
let scb = self.searchController.searchBar
scb.tintColor = UIColor.white
scb.placeholder = "SEARCH"
scb.barTintColor = UIColor.white
if let textfield = scb.value(forKey: "searchField") as? UITextField {
textfield.textColor = UIColor.green
if let backgroundview = textfield.subviews.first {
backgroundview.backgroundColor = UIColor.white
backgroundview.layer.cornerRadius = 10
backgroundview.clipsToBounds = true
}
}
if #available(iOS 11.0, *) {
navigationItem.searchController = searchController
navigationItem.hidesSearchBarWhenScrolling = false
} else {
self.tableView.tableHeaderView = searchController.searchBar
searchController.searchBar.tintColor = UIColor.green
searchController.searchBar.barTintColor = UIColor.green
}
definesPresentationContext = true
observePosts()
}
Add variable of UISearchController
var searchController : UISearchController!
& then add code in viewDidLoad
searchController = UISearchController(searchResultsController: nil)
searchController.delegate = self
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false // displays tableview
let scb = self.searchController.searchBar
scb.tintColor = UIColor.white
scb.placeholder = "SEARCH"
scb.barTintColor = UIColor.white
if let textfield = scb.value(forKey: "searchField") as? UITextField {
textfield.textColor = UIColor.greenColor
if let backgroundview = textfield.subviews.first {
backgroundview.backgroundColor = UIColor.white
backgroundview.layer.cornerRadius = 10
backgroundview.clipsToBounds = true
}
}
if #available(iOS 11.0, *) {
navigationItem.searchController = searchController
navigationItem.hidesSearchBarWhenScrolling = false
} else {
self.tableView.tableHeaderView = searchController.searchBar
searchController.searchBar.tintColor = UIColor.greenColor
searchController.searchBar.barTintColor = UIColor.greenColor
}
definesPresentationContext = true
An UITabbarController does not have a UINavigationController so it doesn't have a UINavigationBar.
So you could do:
Add a cell to your TableView to act like a search bar
Add a Navigationbar to the ViewController
Add a custom View to your View to act as a container
There may be more options, just want to point you into the right direction.
override func viewDidLoad() {
super.viewDidLoad()
searchController = UISearchController(searchResultsController: nil)
searchController.searchBar.autocapitalizationType = .none
if #available(iOS 11.0, *) {
navigationItem.searchController = searchController
// Make the search bar always visible.
navigationItem.hidesSearchBarWhenScrolling = false
} else {
// For iOS 10 and earlier, place the search controller's search bar in the table view's header.
tableView.tableHeaderView = searchController.searchBar
}
searchController.delegate = self
searchController.dimsBackgroundDuringPresentation = false // The default is true.
}
I am integrating UISearchController and UITableViewController in a ViewController.
Below is the code that I have implemented:
func configureSearchController() {
let searchTableViewController = UITableViewController()
self.searchController = UISearchController(searchResultsController: searchTableViewController)
self.searchController.searchResultsUpdater = self;
self.searchController.hidesNavigationBarDuringPresentation = false
self.searchController.searchBar.searchBarStyle = .default
self.navigationItem.titleView = self.searchController.searchBar
self.searchController.searchBar.becomeFirstResponder()
self.searchController.searchBar.placeholder = "Title"
let searchBar = self.searchController.searchBar
if let textfield = searchBar.value(forKey: "searchField") as? UITextField {
textfield.textColor = UIColor.black
if let backgroundview = textfield.subviews.first {
// Background color
backgroundview.backgroundColor = UIColor.white
// Rounded corner
backgroundview.layer.cornerRadius = 5
backgroundview.clipsToBounds = false
}
}
self.definesPresentationContext = true
// Setting delegates and other stuff
searchTableViewController.tableView.dataSource = self
searchTableViewController.tableView.delegate = self
self.searchController.delegate = self
self.searchController.dimsBackgroundDuringPresentation = true
self.searchController.searchBar.delegate = self
}
Now the problem is when I start typing in SearchBar the TableViewController is appearing over SearchBar.
How to add space between SearchBar and TableViewController?
This is how it looks :
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
}