I am working on Swift 3.1, I want a simple search functionality where the search results will show in a popOver manner below the search bar. This is a native offering and should be available using UISearchController. But even after my repeated trials, I could not achieve this. Am I missing something?
I have mentioned the resultsController. Implemented the required delegates and even the data us fed to it. But still its not shown.
Any help will be greatly appreciated. Thanks.
Code:
func initiateView() {
resultsController = ResultsController()
resultsController.table.dataSource = self
searchController = UISearchController.init(searchResultsController: resultsController)
self.view.addSubview(searchController.searchBar)
searchController.searchResultsUpdater = self
searchController.delegate = self
searchController.dimsBackgroundDuringPresentation = false // default is YES
searchController.searchBar.delegate = self // so we can monitor text changes + others
definesPresentationContext = true
feedTable = UITableView()
feedTable.delegate = self
feedTable.dataSource = self
feedTable.separatorStyle = .singleLineEtched
feedTable.register(UITableViewCell.self, forCellReuseIdentifier: "SomeCell")
self.view.addSubview(feedTable)
feedTable.pinToSuperview([.Left, .Right, .Bottom])
feedTable.pinToSuperviewTop(withInset: 50, priority: 100)
}
func updateSearchResults(for searchController: UISearchController)
{
if let searchString = searchController.searchBar.text{
let resultsController = searchController.searchResultsController as! ResultsController
resultsController.resultsArray = feedArray.filter({$0 .contains(searchString)})
resultsController.table.reloadData()
}
}
Related
I added UISearchController programmatically with code
let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Введіть значення для пошуку"
searchController.searchBar.backgroundColor = .white
navigationItem.searchController = searchController
definesPresentationContext = true
}
But it seems that it is not centered vertically. How can I fix it?
Connected SearchController to TableView instead of NavigationItem
tableView.tableHeaderView = searchController.searchBar
It seems like a bug in iOS. For some reason at least on iOS 15 searchbar textfield frame has initial value of y = 1 but after you click on the field and then leave this field it will go to y = 8. Fixing the initial frame manually in viewDidLayoutSubviews solved this problem in my case:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
searchController.searchBar.searchTextField.frame.origin.y = 8
}
Check: Screenshot
I tried solutions to all relevant questions. However none of them helped really.
I am getting a weird gap between table view and search bar when search bar shows results.
Help me find out what's wrong with my code:
the view controller subclasses from UITableViewController, UISearchBarDelegate, UISearchResultsUpdating
var searchController = UISearchController()
var resultsController = UITableViewController()
var refreshController = UIRefreshControl()
in override :
configureSearchController()
resultsController.tableView.delegate = self
resultsController.tableView.dataSource = self
refreshController.attributedTitle = NSAttributedString(string: "")
refreshController.addTarget(self, action: #selector(refreshSelector), for: .valueChanged)
tableView.addSubview(refreshController)
searchController.searchBar.delegate = self
automaticallyAdjustsScrollViewInsets = false
definesPresentationContext = true
#objc func refreshSelector()
{
if(!searchLoaded)
{
searchLoaded = true
self.tableView.tableHeaderView = searchController.searchBar
self.navigationItem.rightBarButtonItem = nil
print( "Got ya")
}
refreshController.endRefreshing()
}
func configureSearchController ()
{
searchController = UISearchController(searchResultsController: resultsController)
searchController.searchResultsUpdater = self
searchController.searchBar.layer.borderWidth = 1;
searchController.searchBar.barTintColor = UIColor.searchBarBackgroundGrey()
searchController.searchBar.layer.borderColor = UIColor.searchBarBackgroundGrey().cgColor
self.navigationController?.navigationBar.shadowImage = UIImage()
}
deployment target has been set as 9.3
I have researched this problem a lot but I have found no solution that would work for me.
Basically, I have a UIViewController that presents UISearchController like this:
let searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.delegate = self
searchController.dimsBackgroundDuringPresentation = false
searchController.searchBar.delegate = self
view.addSubview(searchController.searchBar)
User is then expected to tap the UISearchBar to present searchController and reveal the keyboard. However, a strange thing happens during the transition between controllers.
It seems as if the UISearchController didn't cover the status bar and let you see the UIViewController that presented it below. I would like to find a way to prevent this, i.e. to force the search controller to extend all the way under the status bar.
Things that I have already done:
I have set self.definesPresentationContext = true in viewDidLoad:.
I have found out that this is a known bug, namely rdar://20942583.
I have attempted to circumvent the bug by setting:
self.edgesForExtendedLayout = .All
self.extendedLayoutIncludesOpaqueBars = true
It didn't work.
I'm running out of ideas. Please help.
Thanks a bunch,
Pete.
Facing the same issue and tried everything from here and here and none of this worked for me :(
Best workaround that is working (ugly I know) until I find a better solution:
override func viewDidLoad() {
super.viewDidLoad()
searchController.delegate = self
}
func willPresentSearchController(searchController: UISearchController) {
let statusHeight = UIApplication.sharedApplication().statusBarFrame.size.height
if bgBar == nil {
bgBar = UIView(frame: CGRectMake(0, 0, view.frame.width, (navigationController?.navigationBar.frame.height)! + statusHeight))
bgBar.backgroundColor = UIColor.redColor()
view.addSubview(bgBar)
} else {
bgBar.hidden = false
}
tableView.contentInset.top = statusHeight
}
func willDismissSearchController(searchController: UISearchController) {
bgBar.hidden = true
tableView.contentInset.top = 0
}
On swift 4:
viewWillAppear(_ animated: Bool) {
let statusHeight = UIApplication.shared.statusBarFrame.size.height
let sbview = UIView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: statusHeight))
sbview.backgroundColor = .white
view.addSubview(sbview)
{
I try to show searchController in UIViewcontroller.
This works fine but when I try to write something then search controller is not visible.
My code is as follow:
class tempVC: UIViewController,UISearchBarDelegate,UISearchResultsUpdating {
let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
searchController.searchResultsUpdater = self
searchController.searchBar.delegate = self
searchController.searchBar.placeholder = "Enter name here..."
definesPresentationContext = true
searchController.searchBar.sizeToFit()
searchController.dimsBackgroundDuringPresentation = false
searchController.hidesNavigationBarDuringPresentation=false
//navigationItem.titleView = searchController.searchBar
searchController.searchBar.frame=CGRectMake(0, 64, 320, 44)
self.view.addSubview(searchController.searchBar)
}
// MARK: - UISearchResultsUpdating Delegate
func updateSearchResultsForSearchController(searchController: UISearchController) {
// let searchBar = searchController.searchBar
//let scope = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex]
//filterContentForSearchText(searchController.searchBar.text!, scope: scope)
print("update")
}
}
Please help me to solve this.
Thank you,
class tempVC: UIViewController,UISearchBarDelegate,UISearchResultsUpdating {
let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
searchController.searchResultsUpdater = self
searchController.searchBar.delegate = self
searchController.searchBar.placeholder = "Enter name here..."
definesPresentationContext = true
searchController.searchBar.sizeToFit()
searchController.dimsBackgroundDuringPresentation = false
searchController.hidesNavigationBarDuringPresentation=false
//navigationItem.titleView = searchController.searchBar
searchController.searchBar.frame=CGRectMake(0, 64, 320, 44)
self.view.addSubview(searchController.searchBar)
}
// MARK: - UISearchResultsUpdating Delegate
func updateSearchResultsForSearchController(searchController: UISearchController) {
// let searchBar = searchController.searchBar
//let scope = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex]
//filterContentForSearchText(searchController.searchBar.text!, scope: scope)
print("update")
}
}
I would like uisearchcontroller to start searching after I type at least three characters in search bar. So, what should I do for that ?
func configureSearchController() {
// Initialize and perform a minimum configuration to the search controller.
searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Search"
searchController.searchBar.delegate = self
searchController.searchBar.sizeToFit()
let textFieldInsideSearchBar = searchController.searchBar.valueForKey("searchField") as! UITextField
textFieldInsideSearchBar.font = UIFont(name: "Bauhaus", size: 19)
searchController.searchBar.setImage(UIImage(named: "searchikon"), forSearchBarIcon: UISearchBarIcon.Search, state: UIControlState.Normal);
// Place the search bar view to the tableview headerview.
TableView.tableHeaderView = searchController.searchBar
All you need to is add the single required method for the UISearchController.
func updateSearchResultsForSearchController(searchController: UISearchController) {
if searchController.searchBar.text?.characters.count > 2 {
// Filter your search results here
}
}
You will want to check the the length of the characters in an event which checks the change in the text field:
nameOfString.characters.count