title: iOS Swift 4 searchBar in TableView
body: <p>I build <code>tableView</code> with <code>searchBar</code> inside <code>tableView</code>. What i want to do is.. </p>
  
  <ul>
  <li>search name from <code>searchText</code> and display it on <code>tableView</code>.</li>
  <li>when my <code>searchText</code> is empty, display full user list</li>
  </ul>
  
  <p>i have main <code>array</code> of <code>users</code>:</p>
  
  <pre><code>var users = [User]()
  </code></pre>
  
  <p>current <code>array</code> with use <code>searchBar</code></p>
  
  <pre><code>var currentUserArray = [User]()
  </code></pre>
  
  <p><strong>user model:</strong> </p>
  
  <pre><code>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
  }
  }
  </code></pre>
  
  <p>ViewController: </p>
  
  <pre><code>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) -&gt; Int {
  
      return currentUserArray.count
  }
  
  //cellForRowAt
  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; 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) -&gt; 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) -&gt; UIView? {
  
      return userSearchBar
  }
  func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
      guard !searchText.isEmpty  else { currentUserArray = users; return }
  
      currentUserArray = users.filter({ user -&gt; 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)
  }
  }
  </code></pre>