根据数据动态加载UIController的各个部分

时间:2018-07-06 22:10:35

标签: swift firebase uicollectionview uicollectionviewcell

我正在尝试为应用程序中的“添加朋友”页面实现UICollectionView,并且需要以下功能:

  1. 该视图首次出现时,显示和好友请求用户可能拥有的视图。

  2. 用户在搜索栏中输入用户名,然后(如果找到)该用户名显示在单元格上方的单元格中,以供好友请求。

我一直在尝试通过使用UICollevtionViewController中的部分来实现这一点,但这令人头疼...

enter image description here

import UIKit
import Firebase


class AddUserController: UICollectionViewController, UICollectionViewDelegateFlowLayout, UISearchBarDelegate {


    var searchedUser: User?
    var friendRequests = [User]()
    let cellId = "cellId"
    let headerId = "headerId"


    var sectionCategories = ["Add Friends", "Friend Requests"]

    override func viewDidLoad() {
        super.viewDidLoad()

        collectionView?.delegate = self
        collectionView?.dataSource = self


        collectionView?.register(SearchedUserCell.self, forCellWithReuseIdentifier: cellId)
        collectionView?.register(SectionHeaderView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: headerId)

        getFriendRequests()

    }

    fileprivate func fetchSearchedUsers(username: String) {
        let ref = Database.database().reference().child("usernames")

        ref.child(username).observeSingleEvent(of: .value, with: { (snapshot) in
            // populate user info
            guard let uidOfSearchedUser = snapshot.value as? String else {return}
            Database.database().reference().child("users").child(uidOfSearchedUser).observeSingleEvent(of: .value, with: { (snapshot) in

                guard let userDictionary = snapshot.value as? [String: Any] else {return}
                self.searchedUser = User(uid: uidOfSearchedUser, dictionary: userDictionary)
                self.collectionView?.reloadData()
            }, withCancel: { (err) in
                print("error retrieving user", err)
            })

        }) { (err) in
            print("unable to find user: ", err)
        }
    }

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

        Database.database().reference().child("users").child(uid).child("requests").observe(.value) { (snapshot) in
            guard let requestsDictionary = snapshot.value as? [String: Any] else {return}
            for (key, value) in requestsDictionary {
                print(key, value)
                Database.database().reference().child("users").child(key).observeSingleEvent(of: .value, with: { (snapshot) in
                    guard let userDictionary = snapshot.value as? [String: Any] else {return}
                    let user = User(uid: key, dictionary: userDictionary)
                    print("friend request from: ", user.username)
                    self.friendRequests.append(user)
                })
            }
        }
        self.collectionView?.reloadData()
    }

    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

        if section == 0 {
            return 4
        } else if section == 1 {
            return 1
        }
        return 0
    }


    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        let sendFriendRequestcell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! SearchedUserCell
        let dealWithFriendRequestCell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! SearchedUserCell

        if indexPath.section == 0 {
            //Cell for searched user
            sendFriendRequestcell.user = searchedUser
            return sendFriendRequestcell

        } else if indexPath.section == 1 {
            //Populate all the friend requests that exist

            if friendRequests.count != 0 {
                dealWithFriendRequestCell.user = friendRequests[indexPath.item]
            }
            return dealWithFriendRequestCell
        }

        return sendFriendRequestcell

    }

    override func numberOfSections(in collectionView: UICollectionView) -> Int {
        //Change this to return only 2 only if friend requests exist.

        return 2
    }

    override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {

        switch kind {

        case UICollectionElementKindSectionHeader:

            let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: headerId, for: indexPath) as! SectionHeaderView
            headerView.sectionName = sectionCategories[indexPath.section]
            return headerView

        default:
            assert(false, "Unexpected element kind")
        }

    }

}

我正在使用Firebase来存储/获取搜索到的用户和任何好友请求。我可以在好友请求中看到用户。

我遇到的问题是:

  1. 动态显示部分(除非用户搜索用户,否则不显示“添加朋友”部分和单元格。

  2. 此特定用户(屏幕快照)有一个好友请求,但是未填充该单元来显示该请求。我可以看到我正在正确检索用户。

这样的收藏视图对我来说是最好的方式吗?似乎有点复杂。

1 个答案:

答案 0 :(得分:0)

我说你的问题是国家。这是一个示例,如何使用带有关联值的枚举对状态进行建模。详细了解枚举here

struct User {}
struct UserRequest {}

class Controller: NSObject {
    var collectionView: NSCollectionView!

    enum Sections: Int {
        case searched = 0
        case requests = 1
    }

    enum State {
        case none
        case requests(requests: [UserRequest])
        case searched(user: User)
        case searchedAndRequests(user: User, requests: [UserRequest])
    }

    var state: State = .none {
        didSet {
            collectionView.reloadData()
        }
    }
}

extension Controller: NSCollectionViewDataSource {
    func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
        switch state {
        case .requests(let requests):
            return requests.count
        case .searched(_):
            return 1
        case .searchedAndRequests(_, let requests):
            switch Section(rawValue: section)! {
            case .searched:
                return 1
            case .requests:
                return requests.count
            default:
                fatalError("section not allowed.")
            }
        default:
            fatalError("invalid state.")
        }
    }

    func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
        // Create cell(s) here or later.

        switch state {
        case .searched(let user):
            // Populate user cell and return it.
            break
        case .requests(let requests):
            let request = requests[indexPath.item]
            // Populate cell with request and return it.
        case .searchedAndRequests(let user, let requests):
            switch Section(rawValue: indexPath.section)! {
            case .searched:
                // Populate user cell and return it.
                break
            case .requests:
                let request = requests[indexPath.item]
                // Populate cell with request and return it.
            default:
                fatalError("section not allowed.")
            }
        default:
            fatalError("invalid state")
        }
    }

    func numberOfSections(in collectionView: NSCollectionView) -> Int {
        switch state {
        case .none:
            return 0
        case .requests(_), .searched(_):
            return 1
        case .searchedAndRequests(_, _):
            return 2
        }
    }
}