iOS Swift 4 TableView 中的 searchBar

iOS Swift 4 searchBar in TableView

我在 tableView 中使用 searchBar 构建 tableView。我想做的是..

我有主要的 array of users:

var users = [User]()

当前 array 使用 searchBar

var currentUserArray = [User]()

用户模型:

import Foundation
import Firebase
class User: NSObject {
var id: String?
var name: String?
var login: String?
var email: String?
var profileImageUrl: String?
var role: String?
init(dictionary: [String: AnyObject]) {
    self.id = dictionary["id"] as? String
    self.name = dictionary["name"] as? String
    self.login = dictionary["username"] as? String
    self.email = dictionary["email"] as? String
    self.profileImageUrl = dictionary["profileImageUrl"] as? String
    self.role = dictionary["role"] as? String
}
}

ViewController:

import Foundation
import UIKit
import Firebase
class HomeViewController:UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate {

var users = [User]()
var currentUserArray = [User]()
let cellId = "cellId"

@objc func handleCancel() {
    dismiss(animated: true, completion: nil)
}

//numberOfRowsInSection
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    return currentUserArray.count
}

//cellForRowAt
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! UserCell

    let user = currentUserArray[indexPath.row]
    cell.textLabel?.text = user.name
    cell.detailTextLabel?.text = user.email

    cell.selectionStyle = UITableViewCellSelectionStyle.none
    cell.backgroundColor = .clear

    if let profileImageUrl = user.profileImageUrl {
        cell.profileImageView.loadImageUsingCacheWithUrlString(profileImageUrl)
    }

    return cell
}

//heightForRowAt
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

    return 52
}

var messageController: MessagesController?
//didSelectRowAt
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    let user = self.currentUserArray[indexPath.row]
    self.messageController?.showChatControllerForUser(user)
    print("Dismiss completed1")
}

@IBOutlet weak var usersDisplayTableView: UITableView!
@IBOutlet weak var userSearchBar: UISearchBar!

override func viewDidLoad() {
    super.viewDidLoad()

    currentUserArray = users
    setUpSearchBar()
    setUpTableView()
    fetchUser()
    alterLayout()

    //top title
    self.title = "Contacts"
}

//logout Top bar Button
@IBAction func handleLogout(_ sender:Any) {
    try! Auth.auth().signOut()
    self.dismiss(animated: true, completion: nil)
}

//fetchUser
func fetchUser() {
    Database.database().reference().child("users").observe(.childAdded, with: { (snapshot) in

        if let dictionary = snapshot.value as? [String: AnyObject] {
            let user = User(dictionary: dictionary)
            user.id = snapshot.key
            self.currentUserArray.append(user)

            //this will crash because of background thread, so lets use dispatch_async to fix
            DispatchQueue.main.async(execute: {
                self.usersDisplayTableView.reloadData()
            })

            user.name = dictionary["name"] as? String
        }

    }, withCancel: nil)
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

    return userSearchBar
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    guard !searchText.isEmpty  else { currentUserArray = users; return }

    currentUserArray = users.filter({ user -> Bool in
        return user.name!.lowercased().contains(searchText.lowercased())
    })
    usersDisplayTableView.reloadData()

}

func alterLayout() {
    userSearchBar.placeholder = "Search Animal by Name"
}

private func setUpSearchBar() {
    userSearchBar.showsScopeBar = false
    userSearchBar.delegate = self
}

private func setUpTableView() {

    //definesPresentationContext = true
    usersDisplayTableView.delegate = self
    usersDisplayTableView.dataSource = self
    usersDisplayTableView.backgroundColor = .clear
    usersDisplayTableView.separatorColor = UIColor.black
    self.view.backgroundColor = UIColor(red: 24.0/255.0, green: 34.0/255.0, blue: 45.0/255.0, alpha: 1.0)
    usersDisplayTableView.register(UserCell.self, forCellReuseIdentifier: cellId)
}
}

您需要做的是使用 currentuserArray 作为 tableview

中的数据源

更新您的搜索方法
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    guard !searchText.isEmpty  else { currentUserArray = users; return }

    currentUserArray = users.filter({ user -> Bool in
        return user.name!.lowercased().contains(searchText.lowercased())
    })
    usersDisplayTableView.reloadData()

}

并且当您分配 users 添加以下行时

currentUserArray = users

希望对您有所帮助

编辑

func fetchUser() {
    Database.database().reference().child("users").observe(.childAdded, with: { (snapshot) in

        if let dictionary = snapshot.value as? [String: AnyObject] {
            let user = User(dictionary: dictionary)
            user.id = snapshot.key
            self.currentUserArray.append(user)
            users = currentUserArray // THIS WILL KEEP users AS COPY OF MAIN SOURCE AND SEARCH FILTER APPLY ON IT
            //this will crash because of background thread, so lets use dispatch_async to fix
            DispatchQueue.main.async(execute: {
                self.usersDisplayTableView.reloadData()
            })

            user.name = dictionary["name"] as? String
        }

    }, withCancel: nil)
}

如果您使用 UINavigationController,您可以在 viewDidLoad 中使用此代码创建 searchBar,并让 OS 处理显示和隐藏 searchBar 使用滑动手势:

navigationItem.searchController = UISearchController(searchResultsController: nil)