获取 TableviewCells 以显示从 firebase 提取的不同数据并在 CollectionView 中显示它们
Posted
技术标签:
【中文标题】获取 TableviewCells 以显示从 firebase 提取的不同数据并在 CollectionView 中显示它们【英文标题】:Get TableviewCells to display different data that is extracted from firebase and show them in CollectionView 【发布时间】:2020-03-17 04:20:41 【问题描述】:我有这两个结构,我从 Firebase Database
获取的数据,我不知道如何让每个 tableview 单元格显示不同的集合视图,我在 xib 文件中有两个单元格(TableviewCell 和 CollectionViewCell)但无法按照我想要的方式获得它们。
我附上了我的ViewController
和 TableViewCell 类。请帮忙
struct Clothes
var price: Double
var imgClUrl: String
var id: String
var isActive: Bool = true
var timeStamp: Timestamp
var stock: Double
var name: String
init(data : [String : Any])
self.price = data["price"] as? Double ?? 0
self.imgClUrl = data["imgClUrl"] as? String ?? ""
self.id = data["id"] as? String ?? ""
self.isActive = data["isActive"] as? Bool ?? true
self.timeStamp = data["timeStamp"] as? Timestamp ?? Timestamp()
self.stock = data["stock"] as? Double ?? 0
self.name = data["name"] as? String ?? ""
struct TypesOfCLothing
var title : String
var id : String
var clothes : [Clothes]
init (data : [String : Any])
self.title = data["title"] as? String ?? ""
self.id = data["id"] as? String ?? ""
self.clothes = data["Clothes"] as! [Clothes]
class eachStoreTableViewCell: UITableViewCell
@IBOutlet weak var eachRowCollView: UICollectionView!
@IBOutlet weak var eachRowLbl: UILabel!
var clothes = [Clothes]()
override func awakeFromNib()
super.awakeFromNib()
eachRowCollView?.reloadData()
eachRowCollView?.delegate = self
eachRowCollView?.dataSource = self
self.eachRowCollView?.register(UINib(nibName: "RowColectionView", bundle: nil), forCellWithReuseIdentifier: Identifiers.ClothesCell)
override func setSelected(_ selected: Bool, animated: Bool)
super.setSelected(selected, animated: animated)
func configureCell(clothingType: TypesOfCLothing)
eachRowLbl?.text = clothingType.title
extension eachStoreTableViewCell: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return clothes.count
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Identifiers.ClothesCell, for: indexPath) as? RowColectionView
cell.configureCell(clothes: clothes[indexPath.item])
return cell
return UICollectionViewCell()
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
return CGSize(width: 160, height: 180)
class EachStoreVC: UIViewController
@IBOutlet weak var StoreTblView: UITableView!
var typesOfClothing = [TypesOfCLothing]()
var tienda: Tiendas!
let db = Firestore.firestore()
var listener : ListenerRegistration!
override func viewDidLoad()
super.viewDidLoad()
// StoreTblView?.delegate = self
// StoreTblView?.dataSource = self
StoreTblView?.register(UINib(nibName: "eachStoreTblViewCell", bundle: nil), forCellReuseIdentifier: Identifiers.ClothingTypeCell)
StoreTblView?.cellLayoutMarginsFollowReadableWidth = false
override func viewDidAppear(_ animated: Bool)
override func viewDidDisappear(_ animated: Bool)
func numberOfSections(in tableView: UITableView) -> Int
return 1
extension EachStoreVC : UITableViewDelegate, UITableViewDataSource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return typesOfClothing.count
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
if let cell = tableView.dequeueReusableCell(withIdentifier: Identifiers.ClothingTypeCell, for: indexPath) as? eachStoreTableViewCell
cell.configureCell(clothingType: typesOfClothing[indexPath.row])
cell.frame = CGRect(x: 0, y: 0, width: StoreTblView.frame.size.width, height: cell.frame.size.height)
return cell
return UITableViewCell()
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
return 200
编辑 collectionView 和 Tableview 现在显示正常,但我无法从 firebase 获取数据,我在每个 TypesOfClothing 文档中有一组文档引用,代码如下。我还更新了我的 2 个结构。
func getRowData()
listener = db.collection("TypesOfClothing").addSnapshotListener( (snap, error) in
if let error = error
debugPrint(error.localizedDescription)
return
snap?.documentChanges.forEach( (change) in
let data = change.document.data()
let typesOfClothing = TypesOfCLothing.init(data: data)
switch change.type
case.added:
self.onDocumentAdded(change: change, category: typesOfClothing)
case.modified:
self.onDocumentModified(change: change, category: typesOfClothing)
case.removed:
self.onDocumentRemoved(change: change)
)
)
func onDocumentAdded(change: DocumentChange, category: TypesOfCLothing)
let newIndex = Int(change.newIndex)
typesOfClothing.insert(category, at: newIndex)
StoreTblView?.insertRows(at: [IndexPath(row: newIndex, section: 0)], with: UITableView.RowAnimation.left)
func onDocumentModified(change: DocumentChange, category: TypesOfCLothing)
if change.newIndex == change.oldIndex
let index = Int(change.newIndex)
typesOfClothing[index] = category
StoreTblView?.reloadRows(at: [IndexPath(row: index, section: 0)], with: UITableView.RowAnimation.left)
else
let oldIndex = Int(change.oldIndex)
let newIndex = Int(change.newIndex)
typesOfClothing.remove(at: oldIndex)
typesOfClothing.insert(category, at: newIndex)
StoreTblView?.moveRow(at: IndexPath(row: oldIndex, section: 0), to: IndexPath(row: newIndex, section: 0))
func onDocumentRemoved(change: DocumentChange)
let oldIndex = Int(change.oldIndex)
typesOfClothing.remove(at: Int(oldIndex))
StoreTblView?.deleteRows(at: [IndexPath(row: oldIndex, section: 0)], with: UITableView.RowAnimation.fade)
【问题讨论】:
【参考方案1】:结构体使用如下:
struct TypesOfClothing
var title : String
var clothes: [Clothes]
struct Clothes
var price: Double
var imgClUrl: String
var id: String
var isActive: Bool = true
var timeStamp: Timestamp
var stock: Double
var name: String
在主视图控制器中:尝试这样的代码:
var typesOfClothing: [TypesOfClothing] = []
in numberOfRowsInSection
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return typesOfClothing.count
在 cellForRowAt 中
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
if let cell = tableView.dequeueReusableCell(withIdentifier: Identifiers.ClothingTypeCell, for: indexPath) as? eachStoreTableViewCell
if indexPath.row < typesOfClothing?.count ?? 0
let cellData = typesOfClothing?[indexPath.row]
cell.configureCell(cellData)
return cell
return UITableViewCell()
在 UITableViewCell 类中尝试这样:
class eachStoreTableViewCell: UITableViewCell
@IBOutlet weak var eachRowCollView: UICollectionView!
@IBOutlet weak var eachRowLbl: UILabel!
var clothes = [Clothes]()
override func awakeFromNib()
super.awakeFromNib()
eachRowCollView?.delegate = self
eachRowCollView?.dataSource = self
self.eachRowCollView?.register(UINib(nibName: "RowColectionView", bundle: nil), forCellWithReuseIdentifier: Identifiers.ClothesCell)
override func setSelected(_ selected: Bool, animated: Bool)
super.setSelected(selected, animated: animated)
func configureCell(_ clothingType: TypesOfClothing)
eachRowLbl?.text = clothingType.title
clothes = clothingType.clothes
eachRowCollView?.reloadData()
extension eachStoreTableViewCell: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return clothes.count
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Identifiers.ClothesCell, for: indexPath) as? RowColectionView
cell.configureCell(clothes: clothes[indexPath.item])
return cell
return UICollectionViewCell()
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
return CGSize(width: 160, height: 180)
它会帮助你。
【讨论】:
为什么需要if indexPath.row < typesOfClothing?.count ?? 0
?
用于检查衣服数据是否小于意味着它不会显示并防止数组索引越界
你在numberOfRowsInSection
方法中使用了typesOfClothing.count
。所以上面的检查是没有意义的
另外typesOfClothing
是非可选数组。像typesOfClothing?.count
这样的可选链接会抛出错误
好吧,如果该数组中的数据会频繁更改,那么检查索引是否越界总是更安全。如果您的阵列稳定且不会发生太大变化,那么您可以忽略该行。【参考方案2】:
您可以制作一个结构来加载 tableView 数据
struct ClothingData
var typesOfClothing : String = ""
var clothes : [Clothes] = []
为 tabelView 加载这个 structArray
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return ClothingData.count
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: Identifiers.ClothingTypeCell, for: indexPath) as? eachStoreTableViewCell
let row = ClothingData[indexPath.row]
cell.eachRowLbl?.text = row.typesOfClothing
cell.clothes = row.clothes
// Here you can pass clothesList to tabelViewCell for load collectionView
return cell
【讨论】:
以上是关于获取 TableviewCells 以显示从 firebase 提取的不同数据并在 CollectionView 中显示它们的主要内容,如果未能解决你的问题,请参考以下文章
如何将两个(或更多)tableViewCells 添加在一起以形成“总数”
searchBar 过滤 tableViewCells didSelectItemAt indexPath 显示在 navigationBar Title