【问题标题】:iOS Swift 4 searchBar in TableView表视图中的 iOS Swift 4 搜索栏
【发布时间】:2018-04-23 09:44:08
【问题描述】:

我在tableView 内部构建tableViewsearchBar。我想做的是..

  • searchText 中搜索名称并将其显示在tableView 上。
  • 当我的searchText 为空时,显示完整的用户列表

我有 array 的主要 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
}
}

视图控制器:

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

【问题讨论】:

  • 最好使用UISearchController。你真的有这个问题吗?我没有看到任何问题
  • 您遇到的更新问题?
  • 那是什么问题?现在你只需要使用currentUserArray 作为你的数据源数组

标签: ios swift tableview searchbar


【解决方案1】:

您需要做的是使用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)
}

【讨论】:

  • 我以前这样做过,但是..问题是,在 searchText tableView 中输入文本后什么都没有显示,即使我清除了 searchText 字段,tableView 也没有显示任何内容......所以我卡住了..
  • @HeorhiiHeints 你必须在 tableview 中返回 currentUserArray.count 你这样做的行数吗?
  • 是的..我在返回行数时使用 currentUserArray,甚至在我自定义单元格时也使用..
  • @HeorhiiHeints 那么它应该可以工作..您能否使用 tableview 数据源方法更新您的问题。
  • @HeorhiiHeints 看来您的用户数组是空的!您正在使用此语句 self.currentUserArray.append(user) 填充 currentUserArray,因此您需要在获取 firebase 记录时添加此行 users = currentUserArray
【解决方案2】:

如果您使用UINavigationController,您可以在viewDidLoad 中使用此代码创建searchBar,并让操作系统使用swipeGesture 处理显示和隐藏searchBar

navigationItem.searchController = UISearchController(searchResultsController: nil)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多