我想将模型对象数据源更改为firebase。 我有一个文件作为UICollection视图的数据源,homeViewController.swift。 homeViewController.swift是一个垂直排列的collectionViewCell,每个单元格都有自己的水平排列的collectionViewcell。
这是models.swift文件
import UIKit
import Firebase
class BusinessCategory: NSObject {
var name: String?
var featurebusiness: [SampleBusinesses]?
var type: String?
static func sampleBusinessCategories() -> [BusinessCategory] {
let FastfoodCategory = BusinessCategory()
FastfoodCategory.name = "Fast Food"
var topFastFood = [SampleBusinesses]()
let FastfoodApp = SampleBusinesses()
FastfoodApp.name = "Papa Johns"
FastfoodApp.imageName = "PJ"
topFastFood.append(FastfoodApp)
FastfoodCategory.featurebusiness = topFastFood
let MobilePhoneCategory = BusinessCategory()
MobilePhoneCategory.name = "Mobile Phones"
var topMobilePhoneProvider = [SampleBusinesses]()
//logic
let MobilePhoneApp = SampleBusinesses()
MobilePhoneApp.name = "Verizon"
MobilePhoneApp.imageName = "verizon"
topMobilePhoneProvider.append(MobilePhoneApp)
MobilePhoneCategory.featurebusiness = topMobilePhoneProvider
return [ FastfoodCategory, MobilePhoneCategory ]
我想更改目标文件,以便我的firebase数据库(BusinessCategories)填充它。我尝试了很多选择,但我还没弄清楚。如何将目标文件从物理输入的数据更改为firebase数据?
如果有帮助,这是我的Firebase数据。例如,“Banks”将是类别名称,单元格将由银行下的所有条目填充。
更新: 我想要实现的是类似于Appstore UI,不同类别的应用程序和每个类别是具有水平滚动的集合视图。在我的应用程序中,企业属于firebase中列出的不同类别,每个类别都可以水平滚动。
如何在下面更新我的集合视图属性?
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! CategoryCell
cell.businessCategory = businessCategories?[indexPath.item]
return cell
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if let count = businessCategories?.count{
return count
}
return 0
}
答案 0 :(得分:2)
我希望这会让你开始。拥有数据库的整个架构会更好,但我根据你从截图中看到的内容做了这个。由于您拥有业务树中每个业务的类别类型,因此似乎不需要单独的BusinessCategory树,尽管这完全取决于您。
如果您想提供更完整的数据库截图(只是显示密钥和数据类型的内容),我很乐意修改此代码。
由于我不知道你如何更新你的集合视图,我已经做到了这样它返回一个字典,其中键是类别,值是该类别的bussinesses数组。如果您在集合视图中使用部分,这应该是一种简单的格式。
关于typealias FirebaseRootDictionary,可能需要修改它,因为我猜测你的数据库架构是什么。
如果您对此代码有任何疑问或问题,请在下面添加评论,我会尝试修复它。
所以要获取你的数据:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
Business.getBusinesses { (businesses) in
print(businesses)
}
}
然后在该闭包内部更新集合视图。
import Foundation
import Firebase
final class Business : NSObject {
typealias FirebaseRootDictionary = Dictionary<String,Dictionary<String,Dictionary<String,String>>>
var name: String
var category: String
var email: String
var imageUrl: String
override var description: String {
return "Business(name: \"\(name)\", category: \"\(category)\", email: \"\(email)\", imageUrl: \"\(imageUrl)\")"
}
init(name:String, category:String, email:String, imageUrl:String) {
self.name = name
self.category = category
self.email = email
self.imageUrl = imageUrl
}
class func getBusinesses(completionHandler:@escaping (_ businesses: BusinessesDictionary)->()) { // -> [Business]
let ref = FIRDatabase.database().reference().child("BusinessCategories")
var businesses = BusinessesDictionary()
ref.observeSingleEvent(of: .value, with: { (snapshot) in
guard let value = snapshot.value as? FirebaseRootDictionary else { return }
let categories = value.keys.sorted()
var arr = [Business]() // Array of businesses for category
for cat in categories {
guard let data = value[cat] else { continue }
let businessKeys = data.keys.sorted()
for key in businessKeys {
guard let businessData = data[key] else { continue }
guard let name = businessData["BusinessName"], let category = businessData["Category"], let email = businessData["email"], let imageUrl = businessData["imageUrl"] else { continue }
let business = Business(name: name, category: category, email: email, imageUrl: imageUrl)
arr.append(business)
}
businesses[cat] = arr
arr.removeAll()
}
completionHandler(businesses)
})
}
}
编辑:
因此,对于视图,您有一个tableview,每个部分/类别有一个单元格。单元格具有集合视图,该集合视图具有带有图像视图和标签的集合视图单元格。所以这里我有一个表视图控制器,可以处理所有这些。
import UIKit
typealias BusinessesDictionary = Dictionary<String,[Business]> // I have moved this typealias to here instead of inside the Business Model.
class TableViewController: UITableViewController {
var tableData = BusinessesDictionary()
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.register(CategoryCell.self, forCellReuseIdentifier: "cell")
self.tableView.allowsSelection = false
Business.get { (businesses) in
self.tableData = businesses
self.tableView.reloadData()
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return self.tableData.keys.count
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
let category = self.tableData.keys.sorted()[section]
return category
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? CategoryCell else { return UITableViewCell() }
// Configure the cell...
let category = self.tableData.keys.sorted()[indexPath.section]
guard let businesses = self.tableData[category] else { return UITableViewCell() }
cell.businesses = businesses
return cell
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 120
}
}
表格视图单元格文件。
class CategoryCell: UITableViewCell, UICollectionViewDelegate, UICollectionViewDataSource {
var collectionView: UICollectionView!
var businesses = [Business]()
override func layoutSubviews() {
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) // You may wan to change this as this is the spacing between cells
layout.itemSize = CGSize(width: 100, height: 120) // You may wan to change this as this is the cell size
layout.scrollDirection = .horizontal
collectionView = UICollectionView(frame: self.bounds, collectionViewLayout: layout)
collectionView.topAnchor.constraint(equalTo: self.topAnchor)
collectionView.leftAnchor.constraint(equalTo: self.leftAnchor)
collectionView.rightAnchor.constraint(equalTo: self.rightAnchor)
collectionView.bottomAnchor.constraint(equalTo: self.bottomAnchor)
collectionView.dataSource = self
collectionView.delegate = self
collectionView.register(BusinessCell.self, forCellWithReuseIdentifier: "businessCell")
collectionView.backgroundColor = .white
self.addSubview(collectionView)
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return businesses.count
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "businessCell", for: indexPath) as? BusinessCell else { return UICollectionViewCell() }
// Configure the cell
let business = self.businesses[indexPath.row]
cell.nameLabel.text = business.name
cell.imageView.image = UIImage(named: business.imageUrl)
return cell
}
}
这是集合视图单元格。
class BusinessCell: UICollectionViewCell {
var imageView: UIImageView!
var nameLabel: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
imageView = UIImageView(frame: CGRect(x: 20, y: 20, width: 60, height: 60))
imageView.contentMode = .scaleAspectFit
nameLabel = UILabel(frame: CGRect(x: 0, y: 90, width: 100, height: 30))
nameLabel.font = UIFont.systemFont(ofSize: 11)
nameLabel.textAlignment = .center
self.addSubview(imageView)
self.addSubview(nameLabel)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
以下是我制作的测试数据库的屏幕截图。