Swift 根据数据动态加载UIController的部分
我正在尝试在我的应用程序中为“添加朋友”页面实现UICollectionView,我需要以下功能:Swift 根据数据动态加载UIController的部分,swift,firebase,uicollectionview,uicollectionviewcell,Swift,Firebase,Uicollectionview,Uicollectionviewcell,我正在尝试在我的应用程序中为“添加朋友”页面实现UICollectionView,我需要以下功能: 当视图第一次出现时,显示用户可能有的好友请求 用户将用户名输入搜索栏,然后(如果找到)该用户名显示在好友请求单元格上方的单元格中 我一直试图通过使用UICollevtionViewController中的节来实现这一点,但这一直是一个令人头痛的问题 我正在使用firebase存储/获取我搜索的用户和任何好友请求。我可以在好友请求中看到用户 我面临的问题是: 动态显示部分(“添加朋友”部分和单元格
这样的集合视图是我处理此问题的最佳方式吗?似乎有点复杂。我说您的问题是状态。下面是一个如何使用带有关联值的枚举对状态建模的示例。请阅读有关枚举的详细信息
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")
}
}
}
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
}
}
}