在tableView中搜索后出现错误的单元格图标

时间:2018-04-25 09:31:21

标签: ios swift uitableview firebase uisearchcontroller

我在firebase用户节点中搜索用户,当tableView中的心形按钮被选中时,我将所选用户uid添加到通知节点中。我想将当前用户的待处理好友请求显示为标记的accessoryView按钮。我在我的代码中设法得到了我想要的东西。但是当我使用searchController并搜索待定用户时,我的问题就出现了。当我研究或清除并取消searchBar时,未标记的用户accessoryView按钮显示为已标记。 gif version of my problem

我遗漏了一些我没有经历的事情,我需要帮助。

我搜索了这个主题,但仍然无法解决我的问题。

控制台输出:

Login successfully
UserUID: Bk6o3uUc3sX1W20PMdqbLQoTBWn2 - SenderTag: 0
UserUID: zfwYU7lpWHZwCf8O7wGaV2QMekz1 - SenderTag: 1
UserUID: e6G2axZQNNh9POI2Btkhvce0UXJ3 - SenderTag: 2
UserUID: dx96PxVpMoPqXPiUJEHJvtQmyJ82 - SenderTag: 3
UserUID: zfwYU7lpWHZwCf8O7wGaV2QMekz1 -  Notification: true

import UIKit
import Firebase

class UserViewController: UITableViewController, UISearchBarDelegate, UISearchResultsUpdating {

    let userView = UserView()

    var ref: DatabaseReference!

    var users = [User]()
    var filterUsers = [User]()

    let searchController = UISearchController(searchResultsController: nil)

    override func loadView() {
        // Do not call super!
        self.view = userView
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Delegate and DataSource for TableViewController
        userView.delegate = self
        userView.dataSource = self

        fetchUsers()
        setupSearchController()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        setupNavigationController()
    }

    // MARK: TableView Delegate
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "userCell", for: indexPath) as! UserCell

        let user = searchController.isActive ? filterUsers[indexPath.row] : users[indexPath.row]

        cell.textLabel?.text = user.name?.capitalized
        cell.detailTextLabel?.text = user.email
        cell.accessoryType = .detailDisclosureButton
        cell.accessoryView = cell.beFriendButton

        cell.beFriendButton.tag = indexPath.row

        print("UserUID: \(user.uid!) - SenderTag: \(cell.beFriendButton.tag)")
        observePendingStatus(userUID: user.uid!, sender: cell.beFriendButton)

        cell.beFriendButton.addTarget(self, action: #selector(handleMarkAsFriend(sender:)), for: UIControlEvents.touchUpInside)

        return cell
    }

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

        return searchController.isActive ? filterUsers.count : users.count
    }

    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 72
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    }

    // Setup UINavigationController
    func setupNavigationController() {
        // Hide backBarButtonTitle
        navigationItem.backBarButtonItem = UIBarButtonItem(title:"", style:.plain, target:nil, action:nil)
        // DismissView
        navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(dismissView))
        navigationItem.hidesSearchBarWhenScrolling = false
        tabBarController?.tabBar.isHidden = false
        navigationController?.setNavigationBarHidden(false, animated: true)
        navigationItem.hidesBackButton = false
        navigationController?.navigationBar.prefersLargeTitles = true
        navigationItem.title = "Add Friends"
        navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedStringKey.font : UIFont.boldSystemFont(ofSize: 34), NSAttributedStringKey.foregroundColor : UIColor.preferredColor(r: 0, b: 0, g: 0, a: 1)]
        navigationController?.navigationBar.tintColor = UIColor.preferredColor(r: 255, b: 45, g: 85, a: 1)
    }

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

    // MARK: SearchController
    func setupSearchController() {
        // Search Bar for friend list
        navigationItem.searchController = searchController
        searchController.searchResultsUpdater = self
        searchController.dimsBackgroundDuringPresentation = false
        definesPresentationContext = true
        searchController.hidesNavigationBarDuringPresentation = false
    }

    func updateSearchResults(for searchController: UISearchController) {
        filterSearchController(searchBar: searchController.searchBar)
        tableView.reloadData()
    }

    // MARK: Filter users in searchController
    func filterSearchController(searchBar: UISearchBar) {
        let searchText = searchBar.text ?? ""
        filterUsers = users.filter { user in
            let isMatchingSearchText = (user.name?.lowercased().contains(searchText.lowercased()))! || searchText.lowercased().count == 0
            return isMatchingSearchText
        }
        tableView.reloadData()
    }

    // MARK: Fetch Users
    func fetchUsers() {
        ref = Database.database().reference()
        let userRef = ref.child("users")

        userRef.queryOrdered(byChild: "name").observe(DataEventType.childAdded, with: { (snapshot) in

            guard let values = snapshot.value as? [String: AnyObject] else { return }
            let user = User(dictionary: values)
            user.uid = snapshot.key

            self.users.append(user)

            DispatchQueue.main.async(execute: {
                self.tableView.reloadData()
            })

        }, withCancel: { (error) in
            print(error.localizedDescription)
        })
    }

    // MARK: Mark User
    @objc func handleMarkAsFriend(sender: UIButton) {

        var selectedUser = User()

        selectedUser = searchController.isActive ? filterUsers[sender.tag] : users[sender.tag]

        sender.isSelected = !sender.isSelected
        guard let selectedUserUID = selectedUser.uid else { return }

        if(sender.isSelected == true)
        {
            sender.tintColor = UIColor.preferredColor(r: 255, b: 45, g: 85, a: 1)

            // Add user into notification node
            sendFriendRequest(selectedUserUID: selectedUserUID)
            print("SendFrientRequestTo: \(selectedUserUID) - ButtonTag: \(sender.tag)")
        }
        else
        {
            sender.tintColor = UIColor.preferredColor(r: 0, b: 0, g: 0, a: 1)

            // Delete user from notification node
            cancelFriendRequest(seletedUserUID: selectedUserUID)
            print("CancelFriendRequest: \(selectedUserUID) - ButtonTag: \(sender.tag)")
        }

    }

    // Mark: Send friend request
    func sendFriendRequest(selectedUserUID: String) {
        ref = Database.database().reference()

        guard let fromID = Auth.auth().currentUser?.uid else { return}

        let notificationRef = ref.child("notifications")

        let timestamp = Int(Date().timeIntervalSince1970)

        let values = ["timestamp" : timestamp, "pending": true] as [String : Any]

        notificationRef.child(selectedUserUID).child(fromID).updateChildValues(values) { (error, databaseReference) in

            if let error = error {
                print(error.localizedDescription)
                return
            }
        }
    }

    // Mark: Cancel friend request
    func cancelFriendRequest(seletedUserUID: String) {
        ref = Database.database().reference()

        let notificationRef = ref.child("notifications")

        guard let currentUserUID = Auth.auth().currentUser?.uid else { return }

        notificationRef.child(seletedUserUID).child(currentUserUID).removeValue { (error, databaseReference) in

            if let error = error {
                print(error.localizedDescription)
            }
        }
    }

    // Mark: Observe Pending Status for friend request
    func observePendingStatus(userUID: String, sender: UIButton) {
        ref = Database.database().reference()

        let notificationRef = ref.child("notifications")

        guard let currentUserUID = Auth.auth().currentUser?.uid else { return }

        notificationRef.child(userUID).child(currentUserUID).observe(DataEventType.value, with: { (snapshot) in

            guard let values = snapshot.value as? [String: AnyObject] else { return }

            let notification = NotificationModel(dictionary: values)

            if let pending = notification.pending {
                if pending {
                    print("UserUID: \(userUID) -  Notification: \(pending)")
                    sender.isSelected = true
                    sender.tintColor = UIColor.preferredColor(r: 255, b: 45, g: 85, a: 1)
                }
            }
        }, withCancel: { (error) in
            print(error.localizedDescription)
        })
    }
}

0 个答案:

没有答案