问题描述
我已经建立了一个表格视图,该表格视图从firebase实时数据库中检索数据,并将此数据存储在以下格式的数组(“帖子”)中:
(姓名:无,contactEmail:可选(“ 35345345235”),contactPhoneNum:可选(“ [email protected]”),年龄:可选(“ 25”),性别:无,lastSeen:无, profileDescription:无)
我想实现一个搜索栏来过滤帖子的名称值,并返回在表视图中包含搜索到的名称的帖子,并且不确定如何执行此操作。
这是我的代码:
import UIKit
import Firebase
import FirebaseDatabase
import SwiftKeychainWrapper
import FirebaseAuth
class FeedVC: UITableViewController,UISearchBarDelegate{
@IBOutlet weak var searchBar: UISearchBar!
var currentUserImageUrl: String!
var posts = [postStruct]()
var selectedPost: Post!
var filteredPosts = [postStruct]()
override func viewDidLoad() {
super.viewDidLoad()
getUsersData()
getPosts()
searchBar.delegate = self
// Do any additional setup after loading the view.
// tableView.register(PostCell.self,forCellReuseIdentifier: "PostCell")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// dispose of any resources that can be recreated.
}
func getUsersData(){
guard let userID = Auth.auth().currentUser?.uid else { return }
Database.database().reference().child("users").child(userID).observeSingleEvent(of: .value) { (snapshot) in
if let postDict = snapshot.value as? [String : AnyObject] {
self.tableView.reloadData()
}
}
}
struct postStruct {
let name : String!
let contactEmail : String!
let contactPhoneNum : String!
let age : String!
let gender : String!
let lastSeen : String!
let profileDescription : String!
}
func getPosts() {
let databaseRef = Database.database().reference()
databaseRef.child("firstName").queryOrderedByKey().observe( .childAdded,with: {
snapshot in
let name = (snapshot.value as? NSDictionary)!["name"] as? String
let contactEmail = (snapshot.value as? NSDictionary
)!["contactEmail"] as? String
let contactPhoneNum = (snapshot.value as? NSDictionary
)!["contactPhoneNum"] as? String
let age = (snapshot.value as? NSDictionary
)!["age"] as? String
let gender = (snapshot.value as? NSDictionary
)!["gender"] as? String
let lastSeen = (snapshot.value as? NSDictionary
)!["lastSeen"] as? String
let profileDescription = (snapshot.value as? NSDictionary
)!["profileDescription"] as? String
self.posts.append(postStruct(name: name,contactEmail:contactEmail,contactPhoneNum:contactPhoneNum,age:age,gender:gender,lastSeen:lastSeen,profileDescription:profileDescription))
dispatchQueue.main.async {
self.tableView.reloadData()
}
})
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
print("posts count = ",filteredPosts.count)
return filteredPosts.count
}
override func tableView(_ tableView: UITableView,heightForRowAt indexPath: IndexPath) -> CGFloat {
// tableView.dequeueReusableCell(withIdentifier: "PostCell")!.frame.size.height
return 230
}
override func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "PostCell") as? PostCell else { return UITableViewCell() }
cell.nameLabel?.text = filteredPosts[indexPath.row].name
cell.contactEmailLabel?.text = filteredPosts[indexPath.row].contactEmail
cell.contactPhoneNumLabel?.text = filteredPosts[indexPath.row].contactPhoneNum
cell.ageLabel?.text = filteredPosts[indexPath.row].age
cell.genderLabel?.text = filteredPosts[indexPath.row].gender
cell.lastSeenLabel?.text = filteredPosts[indexPath.row].lastSeen
cell.profileDescriptionLabel?.text = filteredPosts[indexPath.row].profileDescription
print(filteredPosts)
return cell
}
func searchBar(_ searchBar: UISearchBar,textDidChange searchText: String) {
filteredPosts = posts.filter { $0.name?.lowercased().contains(searchText.lowercased()) == true }
}
}
解决方法
在posts
上循环将提供类型Post
而不是String
的元素。解决方法:
func searchBar(_ searchBar: UISearchBar,textDidChange searchText: String) {
filteredPosts = []
for post in posts {
if post.name?.lowercased().contains(searchText.lowercased()) == true {
filteredPosts.append(post)
}
}
}
或者只是使用受{@Jay评论启发的filter
之类的高阶方法。
func searchBar(_ searchBar: UISearchBar,textDidChange searchText: String) {
filteredPosts = posts.filter { $0.name?.lowercased().contains(searchText.lowercased()) == true }
}