简体   繁体   中英

Swift Navigationbar searchbar dismiss search text on click

When I search in the search bar, it gives me results accordingly, but when I click outside to select my option, the search bar placeholder becomes nil and only the searched option is available. To get all the options, I have to again open search bar and press cancel which reloads the tableview to show all the option.

Home Screen
Entering text in search bar
After clicked on the screen

import UIKit

class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource,UISearchControllerDelegate,UISearchBarDelegate {

let locationNames = ["Python", "C#", "Machine Learning"]

let locationImages = [UIImage(named: "hawaiiResort"), UIImage(named: "mountainExpedition"), UIImage(named: "scubaDiving")]

let locationDescription = ["Beautiful resort off the coast of Hawaii", "Exhilarating mountainous expedition through Yosemite National Park", "Awesome Scuba Diving adventure in the Gulf of Mexico"]

let searchController = UISearchController(searchResultsController: nil)
@IBOutlet weak var collectionView: UICollectionView!
var searchResult = [String]()
var searching = false
override func viewDidLoad() {
    navigationItem.title = "Courses"
    navigationController?.navigationBar.prefersLargeTitles = true
    self.navigationItem.largeTitleDisplayMode = .always

    searchController.searchResultsUpdater = self
    searchController.searchBar.delegate = self
    navigationItem.searchController = searchController
    definesPresentationContext = true
    currentPage = 0
}


func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    if(searching){
    return searchResult.count
    }
    else{
    return 3
    }


}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell

    if(searching)
    {
        cell.locationName.text = searchResult[indexPath.row]
        let people = locationNames.index{$0 == String(searchResult[indexPath.row])}
        cell.locationImage.image = locationImages[people ?? 0]
        cell.locationDescription.text = locationDescription[people ?? 0]
    }
    else
    {
    cell.locationImage.image = locationImages[indexPath.row]
    cell.locationName.text = locationNames[indexPath.row]
    cell.locationDescription.text = locationDescription[indexPath.row]
    }


    cell.contentView.layer.cornerRadius = 4.0
    cell.contentView.layer.borderWidth = 1.0
    cell.contentView.layer.borderColor = UIColor.clear.cgColor
    cell.contentView.layer.masksToBounds = false
    cell.layer.shadowColor = UIColor.gray.cgColor
    cell.layer.shadowOffset = CGSize(width: 0, height: 1.0)
    cell.layer.shadowRadius = 4.0
    cell.layer.shadowOpacity = 1.0
    cell.layer.masksToBounds = false
    cell.layer.shadowPath = UIBezierPath(roundedRect: cell.bounds, cornerRadius: cell.contentView.layer.cornerRadius).cgPath


    return cell
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

    let vc = self.storyboard?.instantiateViewController(withIdentifier: "ContentViewController") as! ContentViewController

    vc.selectedCourse = locationNames[indexPath.row]

    self.navigationController?.pushViewController(vc, animated: true)
}
}

extension ViewController: UISearchResultsUpdating{
    func updateSearchResults(for searchController: UISearchController) {
        guard let searchText = searchController.searchBar.text else { return }



    searchResult = locationNames.filter({$0.prefix(searchText.count) == searchText})
    searching = true
    collectionView.reloadData()
}
//    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
//        searchResult = locationNames.filter({$0.prefix(searchText.count) == searchText})
//        searching = true
//        collectionView.reloadData()
//    }

func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
    NSLog("%@",searchBar.text ?? "");
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
    searching = false
    searchBar.text = ""
    collectionView.reloadData()
}
}

I am new to Swift.

First, you should let the updateSearchResults(for:) to make the filtering/updating work, that is its only purpose.

And for the answer, maybe you are setting the isActive method of the UISearchController to false when tapping outside the searchBar , causing the text inside it to be deleted, and not allowing the search controller to update accordingly to reload all the data again.

So, a solution could be adding the searchBarTextDidEndEditing(_) method to reset the data source when the searchBar is no longer the first responder:

func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
    searching = false
    searchResult = locationNames
    collectionView.reloadData()
}

Or even better, let the updateSearchResults(for:) method to update the data automatically:

func updateSearchResults(for searchController: UISearchController) {
    guard let searchText = searchController.searchBar.text else { return }

    searchResult = locationNames.filter({$0.prefix(searchText.count) == searchText})
    collectionView.reloadData()
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM