Swift 5- Firebase-标题中按日期分组 [英] Swift 5- Firebase- Group by date in header

查看:51
本文介绍了Swift 5- Firebase-标题中按日期分组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的主要目标是从Firebase数据库中获取日期,并将其用作部分标题,以便我可以在该标题下加载所有具有相同日期的事件.

My Main goal is to take the Date from the Firebase Database and use is as a section header so that i may load all the events that have the same date under that header.

我希望它显示在我的表格视图中:

I would like it to appear in my table view like this:

9月-标头

-2020年9月29日-sub标头

-September 29,2020 -sub header

-事件

-事件

-事件

-2020年9月30日-sub标头

-september 30, 2020 -sub header

-事件

-事件

-事件

这是我的主要View Controller.

This is my main View Controller.

import UIKit
    import Foundation
    import Firebase
    import FirebaseDatabase

    class EventsTableViewController: UIViewController {
        var sectionNames: [String] = []
        var events: [String: [EventsInfo]] = [:]
        var datref: DatabaseReference!
        var eventView = [EventsInfo]()

        @IBOutlet weak var eventTableView: UITableView!

        override func viewDidLoad() {
            super.viewDidLoad()
            getEventsFromFirebaseDB()
        }
        
        
        deinit {
               datref.removeAllObservers()
           }
           
           private func eventsFetched(_ eventData: [EventsInfo])
           {
               for event in eventData
               {
                guard let eventNameFirstChar = event.date.first else { continue }
                
                   if var eventsForKey = events["\(eventNameFirstChar)"]
                   {
                       eventsForKey.append(event)
                       events["\(eventNameFirstChar)"] = eventsForKey
                   }
                   else
                   {
                       // no users are stored in dictionary for key userNameFirstChar
                       events["\(eventNameFirstChar)"] = [event]
                   }
               }
           
               // sort dictionary keys and set it in sectionNames
               sectionNames = events.map { $0.key }.sorted()
            
            print (sectionNames)
           }
           
        private func getEventsFromFirebaseDB() {
               datref = Database.database().reference().child("events")
                datref.observe(DataEventType.value, with: { [weak self] (snapshot) in
               
                       guard snapshot.childrenCount > 0 else { return }
               
                       var events: [EventsInfo] = []
                       for event in snapshot.children.allObjects as! [DataSnapshot]
                       {
                           let object = event.value as? [String: AnyObject]
               
                           let title = object?["title"]
                           let place = object?["place"]
                           let info = object?["info"]
                           let date = object?["date"]
                           let time = object?["time"]
               
                        let event = EventsInfo(title: title as! String, place: place as! String, info: info as! String, time: time as! String, date: date  as! String)
                           events.append(event)
                            }

                    self?.eventsFetched(events)
                    self?.eventTableView.reloadData()
                        })
            }

        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if segue.identifier == "showEvent"
            {
                if let indexPath = eventTableView.indexPathForSelectedRow
                {
                    let destinationController = segue.destination as! EventsInfoViewController
                    let char = sectionNames[indexPath.section]
                    let event = events[char]![indexPath.row]
                    destinationController.EventsData = event
                }
            }
        }

    }


    extension EventsTableViewController: UITableViewDataSource, UITableViewDelegate {
        
        func numberOfSections(in tableView: UITableView) -> Int {
            sectionNames.count
        }

        func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
              sectionNames[section]
          }


        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            let char = sectionNames[section]
               return events[char]!.count
            }

        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
            let cell = eventTableView.dequeueReusableCell(withIdentifier: "eventsCell") as! EventsTableViewCell
            let char = sectionNames[indexPath.section]
            let event = events[char]![indexPath.row]
            cell.eventTitleLabel.text = event.title
            return cell
        }


    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            performSegue(withIdentifier: "showEvent", sender: self)
    }

这是我的EventsInfo文件

This is my EventsInfo File


import Foundation


class EventsInfo {
    
    var title: String
    var place: String
    var info: String
    var time: String
    var date: String
    
    
    init(title: String, place: String, info: String, time: String, date: String) {
        
        self.title = title
        self.place = place
        self.info = info
        self.time = time
        self.date = date

    }
}

推荐答案

我正在给出一个答案,希望它可以通过一个例子提供一些指导.请注意,这与Firebase无关-纯粹是tableView管理.

I am tossing out an answer in hopes it will provide some direction though an example. Note that none of this is related to Firebase - it's purely tableView management.

我们的应用程序列出了所有水果,其中标题标题是每个水果的名字

Our app is a list is fruits with section titles being the first name of each fruit

A
   Apple
B
   Banana

这是一个用于保存每个部分的数据的结构,然后是一个用于保存这些对象的类数组(tableView dataSource)

Here's a struct to hold each section's data and then a class array to hold those objects (the tableView dataSource)

struct FruitStruct {
   var sectionTitle = ""
   var fruitNameArray = [String]()
}

var fruitDataSource = [FruitStruct]()

然后让我们填充该数据

func setupDataSourceData() {
    let fruitArray = ["Apple", "Pear", "Banana", "Bing Cherry", "Grape", "Orange", "Plum", "Watermelon", "Cantelope"]

    let allFirstChars = fruitArray.map { String($0.prefix(1)) } //get all first chars for section titles
    let sectionTitles = Array(Set(allFirstChars)).sorted() //eliminate dups and sort

    //iterate over the unique section titles and get the fruits that are in that section
    // sort and then craft structs to hold the title and the associated fruits
    sectionTitles.forEach { firstChar in
        let results = fruitArray.filter { $0.prefix(1) == firstChar }
        let sortedFruits = results.sorted()
        let fruit = FruitStruct(sectionTitle: firstChar, fruitNameArray: sortedFruits)
        fruitDataSource.append(fruit)
    }

    //this code is to just output the data to console so you can see what it
    //  looks like. Remove it.
    for fruitData in fruitDataSource {
        print(fruitData.sectionTitle)
        let fruits = fruitData.fruitNameArray
        for fruitName in fruits {
            print("  \(fruitName)")
        }
    }
}

最后,使用tableView委托方法从数据源填充tableView

lastly, the tableView delegate methods to populate the tableView from the dataSource

//
//handle sections
//
func numberOfSections(in tableView: UITableView) -> Int {
    return self.fruitDataSource.count
}

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    let title = self.fruitDataSource[section].sectionTitle
    return title
}

//
//handleTableView rows
//
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    let rowsInSection = self.fruitDataSource[section].fruitNameArray.count
    return rowsInSection
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cellReuseIdentifier", for: indexPath)
    let text = self.fruitDataSource[indexPath.section].fruitNameArray[indexPath.row]
    cell.textLabel?.text = text
    return cell
}

这篇关于Swift 5- Firebase-标题中按日期分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆