Ios 为用户访问正确的indexPath行

Ios 为用户访问正确的indexPath行,ios,swift,firebase,uitableview,uisearchcontroller,Ios,Swift,Firebase,Uitableview,Uisearchcontroller,我正在创建一个消息应用程序,用户可以通过UITableView选择要与谁聊天,问题是显然需要一种搜索特定用户的方法,我已经实现了一个UISearchController,我可以找到我搜索的用户。当我使用override func tableView(tableView:UITableView,didSelectRowAt indexPath:indexPath)方法选择用户时,真正的问题就开始了,因为当我选择用户时,它选择了错误的用户,因为indexPath.row 以下是我的一些代码: New

我正在创建一个消息应用程序,用户可以通过
UITableView
选择要与谁聊天,问题是显然需要一种搜索特定用户的方法,我已经实现了一个
UISearchController
,我可以找到我搜索的用户。当我使用
override func tableView(tableView:UITableView,didSelectRowAt indexPath:indexPath)
方法选择用户时,真正的问题就开始了,因为当我选择用户时,它选择了错误的用户,因为
indexPath.row

以下是我的一些代码: NewMessageController:

import UIKit
import Firebase
import FirebaseDatabase

class NewMessageController: UITableViewController, UISearchBarDelegate, UISearchResultsUpdating {
    
    var searchController = UISearchController()
    
    var activityIndicator = UIActivityIndicatorView(style: .large)
    var aiView = UIView()
    
    let cellId = "cellId"
    
    var users = [User]()
    var filteredUsers = [User]()

    override func viewDidLoad() {
        super.viewDidLoad()
        initSearchController()
        setUpActivityIndicator()
        navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(didTapCancelButton))
        
        tableView.register(UserCell.self, forCellReuseIdentifier: cellId)
        
        startAI()
        fetchUser()
    }
    
    func initSearchController() {
        searchController.loadViewIfNeeded()
        searchController.searchResultsUpdater = self
        searchController.obscuresBackgroundDuringPresentation = false
        searchController.searchBar.enablesReturnKeyAutomatically = false
        searchController.searchBar.returnKeyType = UIReturnKeyType.done
        definesPresentationContext = true
        
        navigationItem.searchController = searchController
        navigationItem.hidesSearchBarWhenScrolling = false
        searchController.searchBar.scopeButtonTitles = ["All"]
        searchController.searchBar.delegate = self
    }
    
    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
//                user.setValuesForKeys(dictionary)
                self.users.append(user)
                DispatchQueue.main.async {
                    self.stopAI()
                    self.tableView.reloadData()
                }
            }
        }, withCancel: nil)
    }
    
    func setUpActivityIndicator() {
        aiView.layer.zPosition = 0.1
        aiView.backgroundColor = UIColor.gray
        aiView.alpha = 0
        aiView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(aiView)
        aiView.centerXAnchor.constraint(equalTo: tableView.centerXAnchor).isActive = true
        aiView.centerYAnchor.constraint(equalTo: tableView.centerYAnchor, constant: -60).isActive = true
        aiView.heightAnchor.constraint(equalToConstant: 150).isActive = true
        aiView.widthAnchor.constraint(equalToConstant: 150).isActive = true
        aiView.layer.masksToBounds = true
        aiView.layer.cornerRadius = 15
        
        activityIndicator.layer.zPosition = 0.2
        activityIndicator.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(activityIndicator)
        activityIndicator.centerXAnchor.constraint(equalTo: aiView.centerXAnchor).isActive = true
        activityIndicator.centerYAnchor.constraint(equalTo: aiView.centerYAnchor).isActive = true
    }
    
    func startAI() {
        activityIndicator.startAnimating()
        aiView.alpha = 0.80
        tableView.isUserInteractionEnabled = false
    }
    
    func stopAI() {
        self.activityIndicator.stopAnimating()
        self.tableView.isUserInteractionEnabled = true
        self.aiView.alpha = 0
    }
    
    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 100
    }
    
    var messagesViewController: MessagesViewController?
    
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        dismiss(animated: true) {
            let selectedUser: User!
            
            if(self.searchController.isActive)
            {
                selectedUser = self.filteredUsers[indexPath.row]
            }
            else
            {
                selectedUser = self.users[indexPath.row]
            }
            
            self.messagesViewController?.showChatControllerForUser(user: selectedUser)
        }
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if (searchController.isActive) {
            
            return filteredUsers.count
        }
        
        return users.count
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        startAI()
        
        let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! UserCell
        let thisUser: User!
        
        if (searchController.isActive) {
            thisUser = filteredUsers[indexPath.row]
        } else {
            thisUser = users[indexPath.row]
        }
        
        
        cell.nameLabel.text = "\(thisUser.firstname!) \(thisUser.surname!)"
        cell.usernameLabel.text = thisUser.username
        cell.profileImageView.loadImageUsingCacheWithUrlString(urlString: thisUser.userImg!)
        cell.timeLabel.text = nil
        
        stopAI()
        return cell
    }
    
    func updateSearchResults(for searchController: UISearchController) {
        let searchBar = searchController.searchBar
        let scopeButton = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex]
        let searchText = searchBar.text!
        
        filterForSearchTextAndScopeButton(searchText: searchText, scopeButton: scopeButton)
    }
    
    func filterForSearchTextAndScopeButton(searchText: String, scopeButton : String = "All") {
        filteredUsers = users.filter {
            user in
            let scopeMatch = (scopeButton == "All" || user.username!.lowercased().contains(scopeButton.lowercased()))
            if(searchController.searchBar.text != "") {
                
                let searchTextMatch = user.username!.lowercased().contains(searchText.lowercased())
                
                return scopeMatch && searchTextMatch
                
            } else {
                
                return scopeMatch
            }
        }
        tableView.reloadData()
    }
}
import UIKit

class User: NSObject {
    
    @objc var id: String?
    @objc var firstname: String?
    @objc var surname: String?
    @objc var email: String?
    @objc var username: String?
    @objc var userImg: String?
    init(dictionary: [String: AnyObject]) {
        self.id = dictionary["id"] as? String
        self.firstname = dictionary["firstname"] as? String
        self.surname = dictionary["surname"] as? String
        self.username = dictionary["username"] as? String
        self.email = dictionary["email"] as? String
        self.userImg = dictionary["userImg"] as? String
    }
}
@objc func showChatControllerForUser(user: User) {
        let chatLogController = ChatLogController(collectionViewLayout: UICollectionViewFlowLayout())
        chatLogController.user = user
        navigationController?.pushViewController(chatLogController, animated: true)
}
用户模型:

import UIKit
import Firebase
import FirebaseDatabase

class NewMessageController: UITableViewController, UISearchBarDelegate, UISearchResultsUpdating {
    
    var searchController = UISearchController()
    
    var activityIndicator = UIActivityIndicatorView(style: .large)
    var aiView = UIView()
    
    let cellId = "cellId"
    
    var users = [User]()
    var filteredUsers = [User]()

    override func viewDidLoad() {
        super.viewDidLoad()
        initSearchController()
        setUpActivityIndicator()
        navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(didTapCancelButton))
        
        tableView.register(UserCell.self, forCellReuseIdentifier: cellId)
        
        startAI()
        fetchUser()
    }
    
    func initSearchController() {
        searchController.loadViewIfNeeded()
        searchController.searchResultsUpdater = self
        searchController.obscuresBackgroundDuringPresentation = false
        searchController.searchBar.enablesReturnKeyAutomatically = false
        searchController.searchBar.returnKeyType = UIReturnKeyType.done
        definesPresentationContext = true
        
        navigationItem.searchController = searchController
        navigationItem.hidesSearchBarWhenScrolling = false
        searchController.searchBar.scopeButtonTitles = ["All"]
        searchController.searchBar.delegate = self
    }
    
    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
//                user.setValuesForKeys(dictionary)
                self.users.append(user)
                DispatchQueue.main.async {
                    self.stopAI()
                    self.tableView.reloadData()
                }
            }
        }, withCancel: nil)
    }
    
    func setUpActivityIndicator() {
        aiView.layer.zPosition = 0.1
        aiView.backgroundColor = UIColor.gray
        aiView.alpha = 0
        aiView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(aiView)
        aiView.centerXAnchor.constraint(equalTo: tableView.centerXAnchor).isActive = true
        aiView.centerYAnchor.constraint(equalTo: tableView.centerYAnchor, constant: -60).isActive = true
        aiView.heightAnchor.constraint(equalToConstant: 150).isActive = true
        aiView.widthAnchor.constraint(equalToConstant: 150).isActive = true
        aiView.layer.masksToBounds = true
        aiView.layer.cornerRadius = 15
        
        activityIndicator.layer.zPosition = 0.2
        activityIndicator.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(activityIndicator)
        activityIndicator.centerXAnchor.constraint(equalTo: aiView.centerXAnchor).isActive = true
        activityIndicator.centerYAnchor.constraint(equalTo: aiView.centerYAnchor).isActive = true
    }
    
    func startAI() {
        activityIndicator.startAnimating()
        aiView.alpha = 0.80
        tableView.isUserInteractionEnabled = false
    }
    
    func stopAI() {
        self.activityIndicator.stopAnimating()
        self.tableView.isUserInteractionEnabled = true
        self.aiView.alpha = 0
    }
    
    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 100
    }
    
    var messagesViewController: MessagesViewController?
    
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        dismiss(animated: true) {
            let selectedUser: User!
            
            if(self.searchController.isActive)
            {
                selectedUser = self.filteredUsers[indexPath.row]
            }
            else
            {
                selectedUser = self.users[indexPath.row]
            }
            
            self.messagesViewController?.showChatControllerForUser(user: selectedUser)
        }
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if (searchController.isActive) {
            
            return filteredUsers.count
        }
        
        return users.count
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        startAI()
        
        let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! UserCell
        let thisUser: User!
        
        if (searchController.isActive) {
            thisUser = filteredUsers[indexPath.row]
        } else {
            thisUser = users[indexPath.row]
        }
        
        
        cell.nameLabel.text = "\(thisUser.firstname!) \(thisUser.surname!)"
        cell.usernameLabel.text = thisUser.username
        cell.profileImageView.loadImageUsingCacheWithUrlString(urlString: thisUser.userImg!)
        cell.timeLabel.text = nil
        
        stopAI()
        return cell
    }
    
    func updateSearchResults(for searchController: UISearchController) {
        let searchBar = searchController.searchBar
        let scopeButton = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex]
        let searchText = searchBar.text!
        
        filterForSearchTextAndScopeButton(searchText: searchText, scopeButton: scopeButton)
    }
    
    func filterForSearchTextAndScopeButton(searchText: String, scopeButton : String = "All") {
        filteredUsers = users.filter {
            user in
            let scopeMatch = (scopeButton == "All" || user.username!.lowercased().contains(scopeButton.lowercased()))
            if(searchController.searchBar.text != "") {
                
                let searchTextMatch = user.username!.lowercased().contains(searchText.lowercased())
                
                return scopeMatch && searchTextMatch
                
            } else {
                
                return scopeMatch
            }
        }
        tableView.reloadData()
    }
}
import UIKit

class User: NSObject {
    
    @objc var id: String?
    @objc var firstname: String?
    @objc var surname: String?
    @objc var email: String?
    @objc var username: String?
    @objc var userImg: String?
    init(dictionary: [String: AnyObject]) {
        self.id = dictionary["id"] as? String
        self.firstname = dictionary["firstname"] as? String
        self.surname = dictionary["surname"] as? String
        self.username = dictionary["username"] as? String
        self.email = dictionary["email"] as? String
        self.userImg = dictionary["userImg"] as? String
    }
}
@objc func showChatControllerForUser(user: User) {
        let chatLogController = ChatLogController(collectionViewLayout: UICollectionViewFlowLayout())
        chatLogController.user = user
        navigationController?.pushViewController(chatLogController, animated: true)
}
我用于显示聊天记录控制器的功能:

import UIKit
import Firebase
import FirebaseDatabase

class NewMessageController: UITableViewController, UISearchBarDelegate, UISearchResultsUpdating {
    
    var searchController = UISearchController()
    
    var activityIndicator = UIActivityIndicatorView(style: .large)
    var aiView = UIView()
    
    let cellId = "cellId"
    
    var users = [User]()
    var filteredUsers = [User]()

    override func viewDidLoad() {
        super.viewDidLoad()
        initSearchController()
        setUpActivityIndicator()
        navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(didTapCancelButton))
        
        tableView.register(UserCell.self, forCellReuseIdentifier: cellId)
        
        startAI()
        fetchUser()
    }
    
    func initSearchController() {
        searchController.loadViewIfNeeded()
        searchController.searchResultsUpdater = self
        searchController.obscuresBackgroundDuringPresentation = false
        searchController.searchBar.enablesReturnKeyAutomatically = false
        searchController.searchBar.returnKeyType = UIReturnKeyType.done
        definesPresentationContext = true
        
        navigationItem.searchController = searchController
        navigationItem.hidesSearchBarWhenScrolling = false
        searchController.searchBar.scopeButtonTitles = ["All"]
        searchController.searchBar.delegate = self
    }
    
    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
//                user.setValuesForKeys(dictionary)
                self.users.append(user)
                DispatchQueue.main.async {
                    self.stopAI()
                    self.tableView.reloadData()
                }
            }
        }, withCancel: nil)
    }
    
    func setUpActivityIndicator() {
        aiView.layer.zPosition = 0.1
        aiView.backgroundColor = UIColor.gray
        aiView.alpha = 0
        aiView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(aiView)
        aiView.centerXAnchor.constraint(equalTo: tableView.centerXAnchor).isActive = true
        aiView.centerYAnchor.constraint(equalTo: tableView.centerYAnchor, constant: -60).isActive = true
        aiView.heightAnchor.constraint(equalToConstant: 150).isActive = true
        aiView.widthAnchor.constraint(equalToConstant: 150).isActive = true
        aiView.layer.masksToBounds = true
        aiView.layer.cornerRadius = 15
        
        activityIndicator.layer.zPosition = 0.2
        activityIndicator.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(activityIndicator)
        activityIndicator.centerXAnchor.constraint(equalTo: aiView.centerXAnchor).isActive = true
        activityIndicator.centerYAnchor.constraint(equalTo: aiView.centerYAnchor).isActive = true
    }
    
    func startAI() {
        activityIndicator.startAnimating()
        aiView.alpha = 0.80
        tableView.isUserInteractionEnabled = false
    }
    
    func stopAI() {
        self.activityIndicator.stopAnimating()
        self.tableView.isUserInteractionEnabled = true
        self.aiView.alpha = 0
    }
    
    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 100
    }
    
    var messagesViewController: MessagesViewController?
    
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        dismiss(animated: true) {
            let selectedUser: User!
            
            if(self.searchController.isActive)
            {
                selectedUser = self.filteredUsers[indexPath.row]
            }
            else
            {
                selectedUser = self.users[indexPath.row]
            }
            
            self.messagesViewController?.showChatControllerForUser(user: selectedUser)
        }
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if (searchController.isActive) {
            
            return filteredUsers.count
        }
        
        return users.count
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        startAI()
        
        let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! UserCell
        let thisUser: User!
        
        if (searchController.isActive) {
            thisUser = filteredUsers[indexPath.row]
        } else {
            thisUser = users[indexPath.row]
        }
        
        
        cell.nameLabel.text = "\(thisUser.firstname!) \(thisUser.surname!)"
        cell.usernameLabel.text = thisUser.username
        cell.profileImageView.loadImageUsingCacheWithUrlString(urlString: thisUser.userImg!)
        cell.timeLabel.text = nil
        
        stopAI()
        return cell
    }
    
    func updateSearchResults(for searchController: UISearchController) {
        let searchBar = searchController.searchBar
        let scopeButton = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex]
        let searchText = searchBar.text!
        
        filterForSearchTextAndScopeButton(searchText: searchText, scopeButton: scopeButton)
    }
    
    func filterForSearchTextAndScopeButton(searchText: String, scopeButton : String = "All") {
        filteredUsers = users.filter {
            user in
            let scopeMatch = (scopeButton == "All" || user.username!.lowercased().contains(scopeButton.lowercased()))
            if(searchController.searchBar.text != "") {
                
                let searchTextMatch = user.username!.lowercased().contains(searchText.lowercased())
                
                return scopeMatch && searchTextMatch
                
            } else {
                
                return scopeMatch
            }
        }
        tableView.reloadData()
    }
}
import UIKit

class User: NSObject {
    
    @objc var id: String?
    @objc var firstname: String?
    @objc var surname: String?
    @objc var email: String?
    @objc var username: String?
    @objc var userImg: String?
    init(dictionary: [String: AnyObject]) {
        self.id = dictionary["id"] as? String
        self.firstname = dictionary["firstname"] as? String
        self.surname = dictionary["surname"] as? String
        self.username = dictionary["username"] as? String
        self.email = dictionary["email"] as? String
        self.userImg = dictionary["userImg"] as? String
    }
}
@objc func showChatControllerForUser(user: User) {
        let chatLogController = ChatLogController(collectionViewLayout: UICollectionViewFlowLayout())
        chatLogController.user = user
        navigationController?.pushViewController(chatLogController, animated: true)
}

更改检测搜索是否处于活动状态的方法

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        dismiss(animated: true) {
            let selectedUser: User!
            
            if(self.searchController.searchBar.text != "")
            {
                selectedUser = self.filteredUsers[indexPath.row]
            }
            else
            {
                selectedUser = self.users[indexPath.row]
            }
            
            self.messagesViewController?.showChatControllerForUser(user: selectedUser)
        }
    }

有时searchController处于活动状态,但ther searhbar为“”,因此无法通过这种方式检查在录制单元格时搜索词是否在哪里

您选择的是什么用户。@kjoe它选择行数,例如,如果第一个未搜索的用户是“John”,我搜索“George”,第一个结果是“George”,如果我选择它,它会因为indexath.row检测到“John”用户。那么您的问题是由于某种原因选择了,SearchController没有处于活动状态。尝试检查而不是搜索控制器。searchBar.isactive==对于searchController.searchBar.text,为true!=“@kjoe谢谢,我想它起作用了。@DiegoFlores没有添加[已解决]。看见