Linking a search bar to a collection view - swift

I have a collection view with cells, I've added the search bar into the navigation bar but I'm having trouble being able to set it so that when I enter text in the search bar it filters the cells to only leave the ones that match the text in the search bar can anyone help me
I know the normal way of using the search bar is with a table view but I'm trying to do it with collection views

Hope below piece of code helps,
class SearchCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Enter text"
searchController.isActive = true
navigationItem.searchController = searchController
definesPresentationContext = true
}
}
extension SearchCollectionViewController: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
let searchText = searchController.searchBar.text
//Here you can update/filter cells in collection view
}
}

Related

How to add SearchController to UITableView Swift?

Im added searchController to tableView header and when table view havent left and right padding all work ok but when im added padding to tableview when im click on search field - searchBar go up and i dont know why and where is the mistake?
it doesn't matter if im set padding on xib or programmatically
#IBOutlet weak var tableView: UITableView!
let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
tableView.tableFooterView = UIView()
configureSearchController()
}
func configureSearchController() {
definesPresentationContext = true
searchController.searchResultsUpdater = self
searchController.searchBar.placeholder = "Search"
searchController.hidesNavigationBarDuringPresentation = false
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.sizeToFit()
searchController.searchBar.barTintColor = .white
tableView.tableHeaderView = searchController.searchBar
}
Im was try added searchController on few ways but always the same results like on screens above.
i also try -> Link of the: answer

Swift - UISearchController Does Not Activate - No Cursor - No Keyboard

I have a UICollectionView with a header view inside of it and a UISearchController in the title of the navigation bar. This code has worked for other views yet does not work for this UICollectionView. I wanted to throw this out to the SO community to see if they can help me solve this problem.
class ViewBusinessProfile: UICollectionViewController, UICollectionViewDelegateFlowLayout, CLLocationManagerDelegate, UISearchControllerDelegate, UISearchBarDelegate, UISearchResultsUpdating {
#IBOutlet var collectionViews: UICollectionView!
var searchController : UISearchController!
override func viewDidLoad() {
super.viewDidLoad()
self.searchController = UISearchController(searchResultsController: nil)
self.searchController.searchResultsUpdater = self
self.searchController.delegate = self
self.searchController.searchBar.delegate = self
self.searchController.hidesNavigationBarDuringPresentation = false
self.searchController.dimsBackgroundDuringPresentation = true
self.searchController.obscuresBackgroundDuringPresentation = false
self.searchController.searchBar.placeholder = "search products..."
//self.searchController.automaticallyShowsCancelButton = false
self.searchController.definesPresentationContext = true
searchController.searchBar.becomeFirstResponder()
navigationItem.titleView = searchController.searchBar
collectionViews.dataSource = self
collectionViews.delegate = self
}
func updateSearchResults(for searchController: UISearchController) {
}
What can I do as far as debugging or anything to try to track down this problem? I have re-created the view in a new UICollectionView and the same problem occurs. The SearchBar is visible but not active to touch yet Back button works on the navigation bar.
These three views all have UISearchControllers on them and I segue between them. The one all the way on the right is where this problem is occurring. The same UISearchController code is used on the left two views and its works perfectly.
Based on what I saw in this related solution, I came up with this code:
import UIKit
class SecondViewController: UIViewController, UISearchControllerDelegate, UISearchBarDelegate {
var searchController : UISearchController!
override func viewDidLoad() {
super.viewDidLoad()
addNavigationBarItems()
}
func addNavigationBarItems() {
self.searchController = searchControllerWith(searchResultsController: nil)
navigationItem.titleView = self.searchController.searchBar
self.definesPresentationContext = true
}
func searchControllerWith(searchResultsController: UIViewController?) -> UISearchController {
let searchController = UISearchController(searchResultsController: searchResultsController)
searchController.delegate = self
// searchController.searchResultsUpdater = self
searchController.searchBar.delegate = self
searchController.hidesNavigationBarDuringPresentation = false
// dimsBackgroundDuringPresentation is deprecated as of iOS 12.0
searchController.dimsBackgroundDuringPresentation = true
searchController.searchBar.searchBarStyle = .prominent
searchController.searchBar.backgroundImage = UIImage()
searchController.searchBar.barTintColor = UIColor(red: 10/255, green: 150/255, blue: 255/255, alpha: 1) //rgb(10, green: 150, blue: 255)
return searchController
}
func updateSearchResults(for searchController: UISearchController) {
}
}
This assumes a navigation bar already exists in the parent view controller (i.e. you don't have to create a new NavigationBar), and results should come out looking like this:

Is there a way to search through content that is fetched from a json file from another view controller?

So I'm working on a project that fetches data from a server and search through it.
I have 2 different Collection view controllers where one shows data of products from a json file and another which fetches data of stores. I have put my searchbar on the homepage and linked it to the searchbar delegate. I tried using it as search controller and to update results too but it fails so I'm stuck trying to find how to have a separate search controller and search result updating view controller. I've watched many tutorials but none actually covers how to search for content in another view controller(especially collection views). Most just search content in the current vc which is easy. Any idea or help is really appreciated.
class FrontPageController: BaseCollectionViewController {
var sections: [Sections]?
override func viewDidLoad() {
super.viewDidLoad()
collectionView?.register(FrontPageCell.self, forCellWithReuseIdentifier: "sectionId")
configureUI()
fetchFrontPageSections()
}
let searchBar = UISearchBar()
func configureUI() {
collectionView?.backgroundColor = .white
searchBar.sizeToFit()
searchBar.delegate = self
searchBar.placeholder = "Search for product or store"
searchBar.autocapitalizationType = .none
navigationController?.navigationBar.barTintColor = .lightGray
navigationController?.navigationBar.isTranslucent = false
navigationController?.navigationBar.tintColor = .primaryDark
showSearchBarButton(shouldShow: true)
definesPresentationContext = true
BaseCollectionViewController
class BaseCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
var searchActive: Bool = false
var products: [Products]?
var filteredProducts = [Products]()
var stores: [Stores]?
var filteredstores = [Stores]()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red
collectionView?.register(ProductsCell.self, forCellWithReuseIdentifier: "productId")
collectionView?.register(StoresCell.self, forCellWithReuseIdentifier: "storeId")
StoreSearchController
class StoreSearchController: BaseCollectionViewController {
override func viewDidLoad() {
super.viewDidLoad()
collectionView?.backgroundColor = .white
fetchStores()
}
ProductSearchController
class ProductSearchController: BaseCollectionViewController {
override func viewDidLoad() {
super.viewDidLoad()
collectionView?.backgroundColor = .white
fetchProducts()
}
So I expect that when I click the search bar in the front-page it should modally present the BaseController class with filtered results of the content in productsearch and storesearch collection view controllers. The front-page has to be the searchbar delegate because that's where i should search from. What class do i make my search controller delegate and what class do i make my searchresultsupdating. Do i need a new vc to handle filtering results? or can base controller do that?
Any help is appreciated.

How to redraw NavigationBar to show SearchController on button press?

I am using a button in my navigationItem.title, which when pressed, I would like to display the navigationItem.searchController.
When cancel is pressed on the search bar, I would like to dismiss the search controller, and redraw the navigation bar.
var universalSearchController = UISearchController(searchResultsController: nil)
override func viewWillAppear(_ animated: Bool) {
// Set search delegate and who will be updating the results
universalSearchController.searchBar.delegate = self
universalSearchController.searchResultsUpdater = self
universalSearchController.delegate = self
definesPresentationContext = true
titleButton.addTarget(self, action: #selector(titleButtonTapped), for: .touchUpInside)
}
Basically everything I have tried is all in here:
#objc func titleButtonTapped() {
// Set the searchController
navigationItem.searchController = universalSearchController
// Below are attempts at redrawing the navigation bar
universalSearchController.searchBar.becomeFirstResponder()
universalSearchController.searchBar.isHidden = false
// Try to refresh by showing/hiding
self.navigationController?.isNavigationBarHidden = true
self.navigationController?.isNavigationBarHidden = false
universalSearchController.view.setNeedsLayout()
universalSearchController.view.layoutIfNeeded()
universalSearchController.view.setNeedsDisplay()
universalSearchController.view.reloadInputViews()
view.setNeedsDisplay()
view.setNeedsLayout()
view.layoutIfNeeded()
view.reloadInputViews()
navigationController!.navigationBar.setNeedsDisplay()
navigationController!.navigationBar.setNeedsLayout()
navigationController!.navigationBar.layoutIfNeeded()
navigationController!.navigationBar.reloadInputViews()
navigationController!.view.setNeedsDisplay()
navigationController!.view.setNeedsLayout()
navigationController!.view.layoutIfNeeded()
navigationController!.view.reloadInputViews()
}
For hiding the searchController:
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
// Get rid of the searchController
navigationItem.searchController = nil
universalSearchController.searchBar.isHidden = true
universalSearchController.searchBar.resignFirstResponder()
// Try to refresh by showing/hiding
self.navigationController?.isNavigationBarHidden = true
self.navigationController?.isNavigationBarHidden = false
navigationController?.navigationBar.backgroundColor = .red
universalSearchController.view.setNeedsLayout()
universalSearchController.view.layoutIfNeeded()
universalSearchController.view.setNeedsDisplay()
universalSearchController.view.reloadInputViews()
view.setNeedsDisplay()
view.setNeedsLayout()
view.layoutIfNeeded()
view.reloadInputViews()
navigationController!.navigationBar.setNeedsDisplay()
navigationController!.navigationBar.setNeedsLayout()
navigationController!.navigationBar.layoutIfNeeded()
navigationController!.navigationBar.reloadInputViews()
}
The weird thing is that if I present a view over my current table view, and then dismiss it, the navigation bar is there.

disable hiding searchBar when scrolling

I am coding to setup search bar (not from storyboard)
here are my codes that related to searchbar:
var searchController = UISearchController(searchResultsController: nil)
func setupNavBar() {
self.navigationItem.title = "Tools"
self.navigationController?.navigationBar.prefersLargeTitles = true
navigationItem.hidesSearchBarWhenScrolling = false
}
func configureSearchController() {
filteredData = toolsList.allTools
searchController.searchResultsUpdater = self
searchController.hidesNavigationBarDuringPresentation = false
searchController.dimsBackgroundDuringPresentation = false
searchController.searchBar.searchBarStyle = .minimal
searchController.searchBar.tintColor = .purple
tableView.tableHeaderView = searchController.searchBar
searchController.searchBar.placeholder = "Search for tools"
}
override func viewDidLoad() {
super.viewDidLoad()
setupNavBar()
tableViewConfigurations()
configureSearchController()
}
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
isSearching = true
tableView.reloadData()
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
isSearching = false
tableView.reloadData()
}
although with this line of code i ask to disable hiding search bar when scrolling, it is still hiding.
navigationItem.hidesSearchBarWhenScrolling = false
May i ask you to guide me to how i can disable it?
Thank you very much
Looking at Apple's docs I found this:
You must configure the searchController property for this property
[hidesSearchBarWhenScrolling] to have any effect. The navigation
controller hides and shows only the search bar provided by the search
controller in that property.
I'd try adding searchController to navigationItem.
#very_supercharged thanks 😊 i have transferred searchBar from table view to navigationBar
i have changed:
tableView.tableHeaderView = searchController.searchBar
to
navigationItem.searchController = searchController
And now, searchBar does not hide when scrolling.