I am working with FSCalendar for my application. I am needing help listing the specific events from my collection view in my calendar and showing in the tableview below it. So when the user clicks on a cell (i.e. a date) on the calendar. The tableview will update and display the specific event for that day. I have checked the documentation for this and there is none for this specific task and i have looked at several other places. I would be grateful for some code examples as i am very new to using FSCalendar and implementing it. Thanks
My current app page:
some of my relevant code:
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, FSCalendarDelegate, FSCalendarDataSource, FSCalendarDelegateAppearance, UIGestureRecognizerDelegate {
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var calendar: FSCalendar!
@IBOutlet weak var animationSwitch: UISwitch!
@IBOutlet weak var calendarHeightConstraint: NSLayoutConstraint!
fileprivate let gregorian: Calendar = Calendar(identifier: .gregorian)
var datesWithEvent = ["2020-12-23","2020-12-16","2020-12-18","2020-12-14","2020-12-06"]
var datesWithMultipleEvents = ["2020-12-03","2020-12-13","2020-12-11","2020-10-03","2020-12-06"]
fileprivate lazy var dateFormatter2: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
override func viewDidLoad() {
super.viewDidLoad()
calendar.select(Date())
self.view.addGestureRecognizer(self.scopeGesture)
self.tableView.panGestureRecognizer.require(toFail: self.scopeGesture)
calendar.scope = .week
// calendar.scrollDirection = .horizontal
calendar.accessibilityIdentifier = "calendar"
}
func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) {
print("did select date \(self.dateFormatter2.string(from: date))")
let selectedDates = calendar.selectedDates.map({self.dateFormatter2.string(from: $0)})
print("selected dates is \(selectedDates)")
if monthPosition == .next || monthPosition == .previous {
calendar.setCurrentPage(date, animated: true)
}
}
func calendarCurrentPageDidChange(_ calendar: FSCalendar) {
print("\(self.dateFormatter2.string(from: calendar.currentPage))")
}
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return [2,20] [section]
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let identifier = ["cell_month", "cell_week"][indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: identifier)!
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")!
return cell
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
if indexPath.section == 0 {
let scope: FSCalendarScope = (indexPath.row == 0) ? .month : .week
self.calendar.setScope(scope, animated: self.animationSwitch.isOn)
}
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 10
}
@IBAction func toggleClicked(sender: AnyObject) {
if self.calendar.scope == .month {
self.calendar.setScope(.week, animated: self.animationSwitch.isOn)
}else {
self.calendar.setScope(.month, animated: self.animationSwitch.isOn)
}
}
func calendar(_ calendar: FSCalendar, numberOfEventsFor date: Date) -> Int {
let dateString = dateFormatter2.string(from: date)
if self.datesWithEvent.contains(dateString){
return 1
}
if self.datesWithMultipleEvents.contains(dateString) {
return 2
}
return 0
}
func calendar(_ calendar: FSCalendar, appearance: FSCalendarAppearance, eventDefaultColorsFor date: Date) -> [UIColor]? {
let key = self.dateFormatter2.string(from: date)
if self.datesWithMultipleEvents.contains(key){
return [UIColor.blue]
}
return nil
}
}
I did it this way: In my "didSelect date" method I reformat the date and then I call a handler for Firebase, where I search for the specific date. I use a wherefield method for Firebase, that searches all events matching that date. Those events get listed in an array. I then use that array for listing the wanted events.
In my Viewcontroller
func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) {
let formatter = DateFormatter()
formatter.dateFormat = "dd/MM-yyyy"
let result = formatter.string(from: date)
EventHandler.readEventAtDate(date: result, tableView: eventTable)
}
In my handler:
static func readEventAtDate(date: String, tableView: UITableView) {
//To feed tableview with specific date
database.collection("Events").whereField("date", isEqualTo: date).getDocuments { (query, error) in
if error != nil {
print("Error: \(String(describing: error))")
} else {
self.eventByDate.removeAll()
for event in query!.documents {
let map = event.data()
let header = map["header"] as! String
let text = map["text"] as! String
let place = map["place"] as! String
let responsible = map["responsible"] as! String
let time = map["time"] as! String
let date = map["date"] as! String
let coordinates = map["coordinates"] as! GeoPoint
let readEvent = Event(eventID: event.documentID, header: header, text: text, place: place, responsible: responsible, time: time, date: date, coordinates: coordinates)
eventByDate.append(readEvent)
}
DispatchQueue.main.async {
tableView.reloadData()
}
}
}
}
In my tableview
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return EventHandler.eventByDate.count
}