iOS Swift 4 searchBar in TableView

让人想犯罪 __ 提交于 2020-01-14 03:11:10

问题


I build tableView with searchBar inside tableView. What i want to do is..

  • search name from searchText and display it on tableView.
  • when my searchText is empty, display full user list

i have main array of users:

var users = [User]()

current array with use searchBar

var currentUserArray = [User]()

user model:

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)
}
}

回答1:


What you have to do is use currentuserArray as your datasource in tableview

update your search method with

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()

}

And when you assigning your users add following line

currentUserArray = users

hope it is helpful

EDIT

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)
}



回答2:


If you use UINavigationController you can create the searchBar with this code in viewDidLoad and let the OS handle the showing and hiding searchBar with swipeGesture:

navigationItem.searchController = UISearchController(searchResultsController: nil)


来源:https://stackoverflow.com/questions/49977942/ios-swift-4-searchbar-in-tableview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!