本文介绍了如何使 firebase 数据库数据成为 UICollection View 的数据源?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将我的模型对象数据源更改为 firebase.我有一个文件作为 UICollection 视图的数据源 homeViewController.swift .homeViewController.swift 是一个垂直排列的collectionViewCell,每个cell都有自己水平排列的collectionViewcell.

I want to change my model object datasource to firebase.I have a file that serves as the datasource for the UICollection view, homeViewController.swift . homeViewController.swift is a vertically arranged collectionViewCell and each cell has its own horizontally arranged collectionViewcell.

这是 models.swift 文件

This is the models.swift file

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 数据?

I want to change the object file so that it is populated by my firebase database (BusinessCategories). I have tried many options but I have not been able to figure it out. How do I change my object file from the physically entered data to firebase data?

如果有帮助,这是我的 Firebase 数据.例如,银行"将是类别名称,单元格将由银行下的所有条目填充.

Here is my Firebase data if it helps. For example "Banks" will be category name and the cell will be populated by all the entries under banks.

更新:我想要实现的类似于 Appstore UI,不同类别的应用程序和每个类别都是具有水平滚动的集合视图.在我的应用程序中,企业位于 firebase 中列出的不同类别中,并且每个类别都可以水平滚动.

Update:What I am trying to achieve is similar to Appstore UI that different categories of apps and each category is a collection view with an horizontal scroll. In my application, Businesses are in different categories listed in firebase and each category is scrollable horizontally.

如何在下面更新我的集合视图属性?

how do I update my collection view attributes below?

 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
}

推荐答案

我希望这能让你开始.拥有数据库的整个架构会更好,但我是根据从您的屏幕截图中看到的内容制作的.似乎也不需要单独的 BusinessCategory 树,因为您在业务树中拥有每个业务的类别类型,尽管这完全取决于您.

I hope this will get you started. It would be better to have the whole schema of the database, but I have made this based on what I could see from your screenshot. It also seems that having a separate BusinessCategory tree is not needed since you have the category type for each business in the Business tree, although that is completely up to you.

如果您想提供更完整的数据库屏幕截图(仅显示键和数据类型),我很乐意修改此代码.

If you want to provide a more complete screenshot of your database (just something that shows the keys and data types), I would be happy to modify this code.

因为我不知道你如何更新你的集合视图,所以我做了它,所以它返回一个字典,其中键是类别,值是该类别的业务数组.如果您在集合视图中使用部分,这应该是一种简单的格式.

Since I don't know how you update your collection view, I have made it so it returns a Dictionary where the key is the category and the value is an array of bussinesses of that category. This should be an easy format if you are using sections in your collection view.

关于 typealias FirebaseRootDictionary,它可能需要修改,因为我猜测您的数据库架构是什么.

With regards to the typealias FirebaseRootDictionary, it might need to be modified as I was guessing on what your database schema was.

如果您对此代码有任何疑问或问题,请在下方发表评论,我会尽力解决.

If you have any questions or problems with this code just put a comment beneath, and I'll try to fix it.

所以要获取您的数据:

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    Business.getBusinesses { (businesses) in

        print(businesses)
    }
}

然后在该闭包中更新集合视图.

Then inside that closure have it update the collection view.

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)
        })
    }
}

因此,对于视图,您有一个表格视图,每个部分/类别有一个单元格.该单元格具有一个集合视图,该集合视图具有一个带有图像视图和标签的集合视图单元格.所以这里我有一个表格视图控制器来处理所有这些.

So for the view, you have a tableview with one cell per section/category. The cell has a collection view, which has a collection view cell with a image view and label. So here I have a table view controller that will handle all that.

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)
    }
}

这是我做的测试数据库的截图.

Here is a screenshot of the test database I made.

这篇关于如何使 firebase 数据库数据成为 UICollection View 的数据源?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-28 01:29