Swift Navigationbar 搜索栏在单击时关闭搜索文本

Posted

技术标签:

【中文标题】Swift Navigationbar 搜索栏在单击时关闭搜索文本【英文标题】:Swift Navigationbar searchbar dismiss search text on click 【发布时间】:2019-01-10 18:56:04 【问题描述】:

当我在搜索栏中搜索时,它会为我提供相应的结果,但是当我在外部单击以选择我的选项时,搜索栏占位符变为 nil,并且只有搜索到的选项可用。要获得所有选项,我必须再次打开搜索栏并按取消,这会重新加载 tableview 以显示所有选项。

Home ScreenEntering text in search barAfter 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()


我是 Swift 新手。

【问题讨论】:

您能分享更多关于您的 searchBar 的设置代码吗?我假设 searching 在您的代码中执行其他操作。我不认为问题出在您共享的代码中,因为当您在搜索栏外部单击时,这些方法都不会被调用,而且搜索栏通常不会自行清除。 【参考方案1】:

首先,您应该让updateSearchResults(for:) 进行过滤/更新工作,这是它的唯一目的。

而对于答案,也许你在searchBar外部点击时将UISearchControllerisActive方法设置为false,导致其中的文本被删除,并且不允许搜索控制器相应地更新以重新加载所有数据。

因此,当searchBar 不再是第一响应者时,解决方案可能是添加searchBarTextDidEndEditing(_) 方法来重置数据源:

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

或者更好,让updateSearchResults(for:)方法自动更新数据:

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

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

【讨论】:

以上是关于Swift Navigationbar 搜索栏在单击时关闭搜索文本的主要内容,如果未能解决你的问题,请参考以下文章

搜索栏在 swift 3 中不起作用。无法将类型 (_) -> Bool 的值转换为预期的参数类型 NSPredicate

iOS 13 - 当搜索主动推送到其他 VC 时,该 VC UITableView 在 Swift 4 中的 NavigationBar 下

使用地址栏在单页应用程序中路由用户

SearchBar 和 NavigationBar 之间的空格 - Swift

向 UINavigationBar 添加搜索按钮:Swift

在 Swift 中设置自定义 NavigationBar 的最简单方法是啥?