我的应用程序中有一个搜索字段,用户可以在其中搜索其他用户。但是我有三个问题:
现在搜索仅适用于具有大写用户名的用户。因此,例如,当我搜索“ Ma”时,显示的唯一用户是“ Makelele”,因为其用户名的首字母大写。例如,即使我应该在tableview上,“ mattgilbert”也根本没有显示。
当用户在表视图中单击时,即使我已取消搜索,该用户仍在表视图中。
i具有此功能,因此仅当用户键入至少2个单词时才开始搜索用户,但是如果用户在搜索字段中键入的字符数超过该单词,则该用户只会在表视图中消失。而且我必须搜索更多字母,以便用户再次出现。
这意味着很多人是否可以帮助我,因为我在搜索内容上花了很多时间。我希望它尽可能地具有成本效益,并且同时具有可扩展性(因此,为什么我在数据库运行其查询之前至少键入了这两个字母)
这是我的代码:
class FollowUsersTableViewController: UIViewController {
@IBOutlet var tableView: UITableView!
var isSearching = false
private var viewIsHiddenObserver: NSKeyValueObservation?
let searchController = UISearchController(searchResultsController: nil)
var usersArray = [UserModel]()
var filteredUsers = [UserModel]()
var loggedInUser: User?
//
var databaseRef = Database.database().reference()
//usikker på den koden over
override func viewDidLoad() {
super.viewDidLoad()
searchController.searchBar.delegate = self
//large title
self.title = "Discover"
if #available(iOS 11.0, *) {
self.navigationController?.navigationBar.prefersLargeTitles = true
} else {
// Fallback on earlier versions
}
self.tableView?.delegate = self
self.tableView?.dataSource = self
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
self.searchController.delegate = self;
definesPresentationContext = true
tableView.tableHeaderView = searchController.searchBar
//self.loadProfileData()
//self.searchBar(searchController.searchBar, textDidChange: searchController.searchBar.text)
}
func searchUsers(text: String) {
if text.count >= 2 {
self.usersArray = [] //clear the array each time
let endingText = text + "\u{f8ff}"
databaseRef.child("profile").queryOrdered(byChild: "username")
.queryStarting(atValue: text)
.queryEnding(atValue: endingText)
.observeSingleEvent(of: .value, with: { snapshot in
for child in snapshot.children {
let childSnap = child as! DataSnapshot
print(childSnap)
let userObj = Mapper<UserModel>().map(JSONObject: childSnap.value!)
userObj?.uid = childSnap.key
if childSnap.key != self.loggedInUser?.uid { //ignore this user
self.usersArray.append(userObj!)
}
}
self.tableView.reloadData()
})
}
} //may need an else statement here to clear the array when there is no text
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let dest = segue.destination as! UserProfileViewController
let obj = sender as! UserModel
let dict = ["uid": obj.uid!, "username": obj.username!, "photoURL": obj.photoURL, "bio": obj.bio]
dest.selectedUser = dict as [String : Any]
}
}
// MARK: - tableview methods
extension FollowUsersTableViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return isSearching ? filteredUsers.count : usersArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! FollowTableViewCell
let user = isSearching ? filteredUsers[indexPath.row] : usersArray[indexPath.row]
cell.title?.text = user.username
if let url = URL(string: user.photoURL ?? "") {
cell.userImage?.sd_setImage(with: url, placeholderImage: #imageLiteral(resourceName: "user_male"), options: .progressiveDownload, completed: nil)
cell.userImage.sd_setIndicatorStyle(.gray)
cell.userImage.sd_showActivityIndicatorView()
}
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 50
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.performSegue(withIdentifier: "user", sender: isSearching ? self.filteredUsers[indexPath.row] : self.usersArray[indexPath.row])
}
}
// MARK: - search methods
extension FollowUsersTableViewController:UISearchResultsUpdating, UISearchControllerDelegate, UISearchBarDelegate {
func updateSearchResults(for searchController: UISearchController) {
searchController.searchResultsController?.view.isHidden = false
self.searchUsers(text: self.searchController.searchBar.text!)
filterContent(searchText: self.searchController.searchBar.text!)
self.tableView.reloadData()
}
func filterContent(searchText:String){
if searchText.count >= 2{
self.filteredUsers = self.usersArray.filter{ user in
return(user.username!.lowercased().contains(searchText.lowercased()))
}
}
}
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
isSearching = true
}
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
isSearching = false
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
isSearching = false
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
isSearching = false
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
self.filteredUsers = self.usersArray.filter{ user in
return(user.username!.lowercased().contains(searchText.lowercased()))
}
if(filteredUsers.count == 0){
isSearching = false
} else {
isSearching = true
}
self.tableView.reloadData()
}
}
编辑:更新的代码
class FollowUsersTableViewController: UIViewController {
@IBOutlet var tableView: UITableView!
var isSearching = false
private var viewIsHiddenObserver: NSKeyValueObservation?
let searchController = UISearchController(searchResultsController: nil)
var usersArray = [UserModel]()
var loggedInUser: User?
//
var databaseRef = Database.database().reference()
//usikker på den koden over
override func viewDidLoad() {
super.viewDidLoad()
searchController.searchBar.delegate = self
//large title
self.title = "Discover"
if #available(iOS 11.0, *) {
self.navigationController?.navigationBar.prefersLargeTitles = true
} else {
// Fallback on earlier versions
}
self.tableView?.delegate = self
self.tableView?.dataSource = self
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
self.searchController.delegate = self;
definesPresentationContext = true
tableView.tableHeaderView = searchController.searchBar
//self.loadProfileData()
//self.searchBar(searchController.searchBar, textDidChange: searchController.searchBar.text)
}
func searchUsers(text: String) {
if text.count >= 2 {
self.usersArray = [] //clear the array each time
let endingText = text + "\u{f8ff}"
databaseRef.child("profile").queryOrdered(byChild: "username")
.queryStarting(atValue: text)
.queryEnding(atValue: endingText)
.observeSingleEvent(of: .value, with: { snapshot in
for child in snapshot.children {
let childSnap = child as! DataSnapshot
print(childSnap)
let userObj = Mapper<UserModel>().map(JSONObject: childSnap.value!)
userObj?.uid = childSnap.key
if childSnap.key != self.loggedInUser?.uid { //ignore this user
self.usersArray.append(userObj!)
}
}
self.tableView.reloadData()
})
}
} //may need an else statement here to clear the array when there is no text
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let dest = segue.destination as! UserProfileViewController
let obj = sender as! UserModel
let dict = ["uid": obj.uid!, "username": obj.username!, "photoURL": obj.photoURL, "bio": obj.bio]
dest.selectedUser = dict as [String : Any]
}
}
// MARK: - tableview methods
extension FollowUsersTableViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return usersArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! FollowTableViewCell
let user = usersArray[indexPath.row]
cell.title?.text = user.username
if let url = URL(string: user.photoURL ?? "") {
cell.userImage?.sd_setImage(with: url, placeholderImage: #imageLiteral(resourceName: "user_male"), options: .progressiveDownload, completed: nil)
cell.userImage.sd_setIndicatorStyle(.gray)
cell.userImage.sd_showActivityIndicatorView()
}
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 50
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.performSegue(withIdentifier: "user", sender: self.usersArray[indexPath.row])
}
}
// MARK: - search methods
extension FollowUsersTableViewController:UISearchResultsUpdating, UISearchControllerDelegate, UISearchBarDelegate {
func updateSearchResults(for searchController: UISearchController) {
searchController.searchResultsController?.view.isHidden = false
self.searchUsers(text: self.searchController.searchBar.text!)
//filterContent(searchText: self.searchController.searchBar.text!)
self.tableView.reloadData()
}
/*
func filterContent(searchText:String){
if searchText.count >= 2{
self.filteredUsers = self.usersArray.filter{ user in
return(user.username!.lowercased().contains(searchText.lowercased()))
}
}
}
*/
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
isSearching = true
}
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
isSearching = false
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
isSearching = false
self.usersArray = []
self.tableView.reloadData()
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
isSearching = false
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
self.usersArray.filter{ user in
return(user.username!.lowercased().contains(searchText.lowercased()))
}
if(usersArray.count == 0){
isSearching = false
} else {
isSearching = true
}
self.tableView.reloadData()
}
}
答案 0 :(得分:0)
请尝试此操作可能会对您有所帮助。
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
let filteredArray = usersArray.filter { ($0["username"] as! String).range(of: searchText!, options: [.diacriticInsensitive, .caseInsensitive]) != nil }
}
这可能会对您有所帮助。谢谢
答案 1 :(得分:0)
问题#1的答案
1)现在,搜索仅适用于具有大写字母的用户 用户名。例如,当我搜索“ Ma”时,唯一的用户是 显示为“ Makelele”,因为他的用户名的字母大写为 第一个字母。例如,“ mattgilbert”根本不显示,甚至 虽然我应该在tableview上。
Firebase没有任何大写或小写搜索。它只有一个区分大小写的文字字符串查询
典型的解决方案是先存储字符串的“显示”版本,然后在将字符串存储在Firbease中之前,先将字符串在代码中小写,然后再存储字符串的“搜索”版本。例如,这是一个用户节点
users
uid_0
display_name: "Kirk"
search_name: "kirk"
uid_1
display_name: "Spock"
search_name: "spock"
uid_1
display_name: "Montgomery Scott"
search_name: "montgomery scott"
2当用户在表视图中单击时,该用户仍在 tableview,即使我已取消搜索。
如果取消搜索,则应清除dataSource数组并重新加载tableView。
myDataSourceArray = []
self.reloadTableview
3我拥有它,因此仅在用户具有以下条件时才开始搜索用户 输入了至少2个单词,但是如果用户在 用户将仅在tableview中消失。我有 搜索更多字母以使用户再次出现。
我在previous answers中发布的代码可以解决此问题,并且是经过测试的完整解决方案。请返回这些答案-您几乎可以将代码复制并粘贴到项目中,并且可以正常工作。