I've read some Stack OverFlow posts and nothing from there has worked. I have one simple problem that shouldn't be incredibly difficult to solve. I have to stop the search bar from disappearing when scrolling on the tableview that it is attached to.
I have tried:
set the tableview to .plain to make the header view sticky, but that didn't work.
I tried navigationItem.hidesSearchBarWhenScrolling = false, but this may not have worked because searchController.searchBar is set equal to tableView.tableViewHeader.
Here is my viewDidLoad, which should contain the relevant code when this works, if it is indeed possible:
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
tableView.separatorStyle = .none
tableView.backgroundColor = UIColor.init(red: 240/255, green: 246/255, blue: 243/255, alpha: 1)
tableView.register(SearchTableViewCell.self, forCellReuseIdentifier: "SearchTVC")
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
searchController.searchBar.delegate = self
definesPresentationContext = true
navigationController?.navigationBar.isHidden = true
tableView.tableHeaderView = searchController.searchBar
searchController.searchBar.tintColor = .darkGray//UIColor.white
searchController.searchBar.barTintColor = UIColor.convertHexColor(hex: "eaeaea")
navigationItem.hidesSearchBarWhenScrolling = false
searchController.hidesNavigationBarDuringPresentation = false
searchController.searchBar.text = ""
addConstraints()
presentInitialView()
}
Related
I used very similar code for another app and the search bar behaves as it should. For some reason, this code below does not work with my current app. Searching online did not yield any answers. The delegate functions aren't the cause of it as when I comment out all their code, it results in the exact same behavior. In fact, when I comment out most of this code below, it results in the same behavior. I don't know why tapping on search destroys my ui. Am I missing something? I must be...
private func configureSearchBar() {
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
searchController.searchBar.showsCancelButton = true
searchController.searchBar.delegate = self
searchController.searchBar.isUserInteractionEnabled = true
definesPresentationContext = true
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(searchController.searchBar)
searchController.searchBar.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 20).isActive = true
searchController.searchBar.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -20).isActive = true
searchController.searchBar.heightAnchor.constraint(equalToConstant: 55).isActive = true
searchController.searchBar.topAnchor.constraint(equalTo: agendaLabel.bottomAnchor, constant: 8).isActive = true
let color:UIColor = .journeyGold
let lightGold = color.withAlphaComponent(0.5)
searchController.searchBar.tintColor = lightGold
searchController.searchBar.barTintColor = lightGold
searchController.searchBar.backgroundColor = lightGold
searchController.searchBar.layer.borderColor = lightGold.cgColor
navigationItem.hidesSearchBarWhenScrolling = false
searchController.hidesNavigationBarDuringPresentation = true
searchController.searchBar.text = ""
searchController.searchBar.setShowsCancelButton(true, animated: 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'm adding a UISearchController but I keep experiencing spacing problems. In particular, when I conduct a search in the search bar, it shifts up and leaves a black space between the tableview and the search bar.
Then, when I type the the black space disappears but there's a large white space between the search bar and the table.
I tried adding the following line but the spacing problem becomes worse:
searchController.hidesNavigationBarDuringPresentation = false
Any helpful hints would be greatly appreciated.
Here is my current code:
class SearchViewController: UITableViewController {
var searchController: UISearchController!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.clear
view.isOpaque = false
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
//Set up Table View
self.navigationController?.navigationBar.shadowImage = UIImage()
let searchResultsController = UITableViewController(style: .plain)
searchResultsController.tableView.delegate = self
searchResultsController.tableView.dataSource = self
searchResultsController.tableView.rowHeight = 65
searchResultsController.tableView.register(SearchCell.self, forCellReuseIdentifier: "SearchCell")
// Setup Search Controller
searchController = UISearchController(searchResultsController: searchResultsController)
searchController.searchBar.tintColor = UIColor.white
searchController.searchBar.barTintColor = UIColor(red: 34/255, green: 167/255, blue: 240/255, alpha: 1.0)
searchController.searchBar.layer.borderColor = UIColor(red: 34/255, green: 167/255, blue: 240/255, alpha: 1.0).cgColor
searchController.searchBar.layer.borderWidth = 1.00
tableView.tableHeaderView?.addSubview(searchController.searchBar)
let searchBar = searchController.searchBar
searchBar.sizeToFit()
searchBar.placeholder = "Search"
searchController.searchBar.delegate = self
searchController.searchResultsUpdater = self
definesPresentationContext = true
searchController.dimsBackgroundDuringPresentation = false
tableView.tableHeaderView = searchController.searchBar
}
try to Add
self.automaticallyAdjustsScrollViewInsets = false
self.extendedLayoutIncludesOpaqueBars = true
in viewDidload.
or uncheck "Adjust Scroll View Insets"
I'm trying tu put a UIRefreshControl and a UISearchController into a UITableView.
When i pull down to refresh it works well but at first loading the UIRefreshControl is covered by the UISearchController:
Here is my code:
override func viewDidLoad() {
super.viewDidLoad()
self.refreshControl = UIRefreshControl()
self.refreshControl?.backgroundColor=UIColor.clearColor()
self.refreshControl!.addTarget(self, action: #selector(SocialManTableViewController.refresh(_:)), forControlEvents: UIControlEvents.ValueChanged)
self.refreshControl!.tintColor = UIColor(colorLiteralRed: 59/255, green: 89/255, blue: 152/255, alpha: 1)
self.refreshControl!.beginRefreshing()
searchController = UISearchController(searchResultsController: nil)
searchController.searchBar.sizeToFit()
searchController.searchBar.barTintColor = UIColor.clearColor()
searchController.searchBar.backgroundImage = UIImage()
searchController.searchBar.tintColor=UIColor.blackColor()
tableView.setContentOffset(CGPoint(x: 0, y: searchController.searchBar.frame.size.height), animated: false)
tableView.tableHeaderView = searchController.searchBar
definesPresentationContext = true
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
}
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!