UISearchResultsUpdating 不基于 searchBar 文本过滤 collectionView
Posted
技术标签:
【中文标题】UISearchResultsUpdating 不基于 searchBar 文本过滤 collectionView【英文标题】:UISearchResultsUpdating not filtering collectionView based on searchBar text 【发布时间】:2017-09-19 01:47:26 【问题描述】:我正在尝试根据 searchBar 文本输入过滤 collectionView。我能够在 textDidChange 和 updateSearchResults 函数调用上使用数据库中的所有用户加载和填充 UISearchResultsUpdating 类的 collectionView,但 collectionView 不会根据 searchBar 输入进行过滤(它始终显示数据库中的所有用户 - 即使在文本输入上) .我认为棘手的部分是我有一个集合视图(菜单栏类),它委托给其他 2 个集合视图。这些 collectionView 中的每一个都有不同的 searchBar 和 searchController。请参阅随附的屏幕截图和代码以供参考。提前致谢!
// 带有两个 searchControllers 的 searchVC
class SearchVC: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, UISearchControllerDelegate, UISearchBarDelegate
var users = [CurrentTraveler]()
var isSearching = false
var filteredData = [CurrentTraveler]()
var peopleResultsViewController: SearchPeopleResultsVC?
var filtered:[String] = []
var searchActive : Bool = false
var searchPeopleController: UISearchController?
let cellId1 = "cellId1"
let cellId2 = "cellId2"
override func viewDidLoad()
super.viewDidLoad()
setupSearchBar()
setupCollectionView()
func setupSearchBar()
// sets up searchBar for first collectionView...
func setupCollectionView()
contentCollectionView.dataSource = self
contentCollectionView.delegate = self
contentCollectionView.register(SearchPeopleCollectionView.self, forCellWithReuseIdentifier: cellId2)
func scrollToMenuIndex(menuIndex: Int)
let indexPath = IndexPath(item: menuIndex, section: 0)
contentCollectionView.scrollToItem(at: indexPath, at: UICollectionViewScrollPosition(), animated: true)
if indexPath.item == 1
searchPeopleController?.delegate = self
searchPeopleController?.searchBar.delegate = self
peopleResultsViewController = SearchPeopleResultsVC()
searchPeopleController = UISearchController(searchResultsController: peopleResultsViewController)
searchPeopleController?.searchResultsUpdater = peopleResultsViewController
navigationItem.titleView = searchPeopleController?.searchBar
if indexPath.item == 0
// sets up searchController for first collectionView search
//menubar collectionView
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return 2
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId1", for: indexPath)
if indexPath.item == 0
// set up first collectionView in menubar...
if indexPath.item == 1
let usersCell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId2", for: indexPath) as! SearchPeopleCollectionView
usersCell.searchVC = self
return usersCell
return cell
var filterString = ""
didSet
guard filterString != oldValue else return
if filterString.isEmpty
filteredData = users
else
filteredData = users.filter ($0.name?.localizedStandardContains(filterString))!
peopleResultsViewController?.collectionView.reloadData()
func updateSearchResults(for searchPeopleController: UISearchController)
filterString = searchPeopleController.searchBar.text ?? ""
if filterString.isEmpty
filteredData = users
else
filteredData = users.filter ($0.name?.localizedStandardContains(filterString))!
peopleResultsViewController?.collectionView.reloadData()
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String)
// should I do anything here...?
// UISearchResults更新类
class SearchPeopleResultsVC : UIViewController, UISearchResultsUpdating, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UISearchBarDelegate
let cellId = "cellId"
var users = [CurrentTraveler]()
var filteredData = [CurrentTraveler]()
var isSearching = false
var searchVC: SearchVC?
var peopleResultsViewController: SearchPeopleResultsVC?
var searchController: UISearchController?
var searchPeopleCollectionView: SearchPeopleCollectionView?
var filtered:[String] = []
var searchActive : Bool = false
let searchPeopleController = UISearchController(searchResultsController: nil)
lazy var collectionView: UICollectionView =
cv.dataSource = self
cv.delegate = self
return cv
()
override func viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
fetchTravelingUserCell()
func fetchTravelingUserCell()
Database.database().reference().child("users").observe(.childAdded, with: (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject]
let user = CurrentTraveler(dictionary: dictionary)
self.users.append(user)
DispatchQueue.main.async(execute:
self.collectionView.reloadData()
)
, withCancel: nil)
var filterString = ""
didSet
// Return if the filter string hasn't changed.
guard filterString != oldValue else return
if filterString.isEmpty
filteredData = users
else
filteredData = users.filter ($0.name?.localizedStandardContains(filterString))!
collectionView.reloadData()
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
if searchPeopleController.isActive && searchPeopleController.searchBar.text != ""
return filteredData.count
return users.count
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as? BaseGlobalSearchUser else fatalError("Expected to display a `DataItemCollectionViewCell`.")
if searchPeopleController.isActive && searchPeopleController.searchBar.text != ""
cell.currentTraveler = filteredData[indexPath.item]
else
cell.currentTraveler = users[indexPath.item]
return cell
func updateSearchResults(for searchPeopleController: UISearchController)
filterString = searchPeopleController.searchBar.text ?? ""
// does print what user types in the searchBar
print(filterString)
if filterString.isEmpty
filteredData = users
else
filteredData = users.filter ($0.name?.localizedStandardContains(filterString))!
peopleResultsViewController?.collectionView.reloadData()
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String)
if filterString.isEmpty
filteredData = users
else
filteredData = users.filter ($0.name?.localizedStandardContains(filterString))!
self.collectionView.reloadData()
//数据模型类
class CurrentTraveler: SafeJsonObject
var name: String?
var profileImageUrl: String?
var travelingPlace: String?
init(dictionary: [String: AnyObject])
super.init()
self.name = dictionary["name"] as? String
self.profileImageUrl = dictionary["profileImageUrl"] as? String
self.travelingPlace = dictionary["users/uid/Places"] as? String
setValuesForKeys(dictionary)
【问题讨论】:
【参考方案1】:可能是您的filteredString
为空。所以你没有得到价值。
所以尝试如下:
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String)
if filterString.isEmpty
filterString = searchText
if filterString.isEmpty
filteredData = users
else
filteredData = users.filter ($0.name?.localizedStandardContains(filterString))!
self.collectionView.reloadData()
【讨论】:
以上是关于UISearchResultsUpdating 不基于 searchBar 文本过滤 collectionView的主要内容,如果未能解决你的问题,请参考以下文章
如何使 UITableViewController 符合协议 UISearchResultsUpdating?
为啥使用 UISearchResultsUpdating 取消按钮后我的 tableview 是空白的?
Swift:如何对数组中结构的子值使用 UISearchResultsUpdating?