I am using FSCalendar in my application to show calendar and events. So my question is can we achieve events table using FSCalendar or we have to do it by using separate tableview. Thanks in adv.
Asked
Active
Viewed 655 times
0
-
1I will go for separate tableView , The above **Screenshot** is from FSCalendar page under **Achievement of Users** , this feature is not provided with FSCalendar Lib – iOS Geek Jun 26 '18 at 04:14
2 Answers
0
1) put tableview down to the FSCalendar view.
2) Then Get Selected Date DATA And Relaod the tableview.

Ravi Padsala
- 126
- 2
- 10
0
Events list using FSCalendar To display events, here using UICollectionView, and FSCalendar is hiding and showing using UIButton.
Also month name taken from FSCalendar and displaying separately (outside of calendar view) using UILabel.
On clicking on date from calendar collection view scrolls to respective event.
class CalendarViewController: UIViewController {
@IBOutlet var calendarMonthButton: UIButton!
@IBOutlet var calendarMonthArrowImageView: UIImageView!
@IBOutlet var calendarView: UIView!
@IBOutlet var calendarViewHeightConstraint: NSLayoutConstraint!
@IBOutlet var collectionView: UICollectionView!
var interactor: DailyEventsCalendarBusinessLogic?
var events = DailyEventsCalendarModel.ViewModel()
var didFirstLoad = false
var selectedDate: Date?
var selectedMonth = Date()
var highlightedMonth = Date()
var calendar: FSCalendar!
override func viewDidLoad() {
super.viewDidLoad()
initCalendar()
calendar.delegate = self
calendar.dataSource = self
calendarView.alpha = 0
calendarView.isHidden = true
calendarViewHeightConstraint.constant = 8
calendarMonthArrowImageView.transform = CGAffineTransform(scaleX: 1, y: -1)
collectionView.register(UINib(nibName: "EventsCalendarCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "EventsCalendarCollectionViewCell")
collectionView.register(UINib(nibName: "EventsCalendarSectionHeaderView", bundle: nil), forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "EventsCalendarSectionHeaderView")
collectionView.contentInset.bottom = 100
if let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
layout.sectionHeadersPinToVisibleBounds = true
}
TDMAnalytics.sendScreenAnalytics(newScreenName: "Events Calendar", screenClass: "CalendarViewController")
setUpInteractor()
interactor?.fetch(Date(), toDate: DateInRegion(selectedMonth,region: Region.current).dateAtEndOf(.month).dateAtEndOf(.day).date)
}
func initCalendar() {
calendar = FSCalendar(frame: CGRect(x: 0, y: 0, width: self.calendarView.frame.width, height: self.calendarView.frame.height))
calendar.alpha = 1
calendar.center = calendarView.center
let screenSize: CGRect = UIScreen.main.bounds
if screenSize.width >= 375 {
calendar.frame = CGRect(x: 0, y: 0, width: calendarView.frame.width-35, height: calendarView.frame.height)
} else {
calendar.frame = CGRect(x: 0, y: 0, width: calendarView.frame.width, height: calendarView.frame.height)
}
calendar.headerHeight = 0
calendar.placeholderType = .none
calendar.appearance.weekdayTextColor = .lightGray // weekday text color
calendar.appearance.titleDefaultColor = .white // active dates color
calendar.appearance.titleSelectionColor = .black // selected date text color
calendar.appearance.titleTodayColor = .black // todays date text color
calendar.appearance.todayColor = .white // todays date circle color
calendar.appearance.selectionColor = .lightGray // date selection color
calendarView.addSubview(calendar)
calendarCurrentPageDidChange(calendar)
}
func calendarCurrentPageDidChange(_ calendar: FSCalendar) {
let currentPageDate = calendar.currentPage
let month = Calendar.current.component(.month, from: currentPageDate)
let monthName = DateFormatter().monthSymbols[month - 1].capitalized
calendarMonthButton.setTitle(monthName, for: .normal)
}
func setUpInteractor() {
let presenter = DailyEventsCalendarPresenter(displayable: self)
let worker = EventListWorker()
interactor = DailyEventsCalendarInteractor(presenter: presenter, worker: worker)
}
@IBAction func tapCalendarMonthButton(_ sender: Any) {
toggleCalendar()
}
func toggleCalendar(hide: Bool? = nil) {
let hiding: Bool = hide ?? !self.calendarView.isHidden
if (hiding && self.calendarView.isHidden) || (!hiding && !self.calendarView.isHidden) {
return
}
if !hiding {
self.calendarView.isHidden = false
self.calendarView.alpha = 0
self.calendarView.reloadInputViews()
self.updateCalendarLayout()
}
UIView.animate(withDuration: 0.2, delay: 0, options: [.curveEaseInOut], animations: {
if hiding {
self.calendarView.alpha = 0
self.calendarViewHeightConstraint.constant = 8
self.calendarMonthArrowImageView.transform = CGAffineTransform(scaleX: 1, y: -1)
self.calendarView.reloadInputViews()
self.updateCalendarLayout()
} else {
self.calendarView.alpha = 1
self.calendarViewHeightConstraint.constant = 266
self.calendarMonthArrowImageView.transform = .identity
self.calendarView.reloadInputViews()
self.updateCalendarLayout()
}
self.view.layoutIfNeeded()
}) { (completed) in
if hiding {
self.calendarView.isHidden = true
self.updateCalendarLayout()
}
}
}
func updateCalendarLayout() {
calendarView.layoutSubviews()
calendarView.layoutIfNeeded()
calendar.layoutSubviews()
calendar.layoutIfNeeded()
}
func scrollToDate(_ date: Date,animated:Bool = true) {
var foundIdx: Int?
for (idx,eventsDay) in events.eventsDays.enumerated() {
if NSCalendar.current.isDate(date, inSameDayAs: eventsDay.date) {
foundIdx = idx
}
}
if let foundIdx = foundIdx {
if let layoutAttributes = collectionView.layoutAttributesForItem(at: IndexPath(item: 0, section: foundIdx)) {
collectionView.setContentOffset(CGPoint(x: 0, y: layoutAttributes.frame.origin.y - 12), animated: true)
}
} else {
let dateDIR = DateInRegion(date,region:Region.current)
let selectedMonthDIR = DateInRegion(selectedMonth,region:Region.current)
if dateDIR.month == selectedMonthDIR.month && dateDIR.year == selectedMonthDIR.year {
MBProgressHUD.showToast(toastMessage: "There are no events on this date.", duration: .short)
}
}
}
}
extension CalendarViewController: DailyEventsCalendarDisplayable {
func display(_ viewModel: DailyEventsCalendarModel.ViewModel) {
events = viewModel
collectionView.reloadData()
if let startDate = events.startDate {
selectedMonth = startDate
}
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.2) {
if !self.didFirstLoad {
self.scrollToDate(Date().dateAtStartOf(.day),animated:false)
self.didFirstLoad = true
}
}
}
func displayEventWithFeed(_ event: Feed?) {
if let feed = event {
let controllerIdentifier = String(describing: FeedDetailViewController.self)
let feedDetailController = UIStoryboard.controller(controllerIdentifier, storyboardName: .feedDetail) as! FeedDetailViewController
feedDetailController.setUpInteractor()
feedDetailController.interactor?.feed = feed
feedDetailController.isStoreBtnHidden = !feed.showVisitBrand
feedDetailController.type = FavoriteType.event.rawValue
self.present(feedDetailController, animated: true, completion: nil)
//self.parent?.navigationController?.pushViewController(feedDetailController, animated: true)
}
}
}
extension CalendarViewController: UIScrollViewDelegate {
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
toggleCalendar(hide: true)
}
}
extension CalendarViewController: UICollectionViewDataSource {
func numberOfSections(in collectionView: UICollectionView) -> Int {
let days = highlightedMonth.monthDays
if (events.eventsDays.count > days) {
return days
}
return events.eventsDays.count
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
let eventsDay = events.eventsDays[section]
return eventsDay.events.count
}
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
if kind == UICollectionView.elementKindSectionHeader {
if let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "EventsCalendarSectionHeaderView", for: indexPath) as? EventsCalendarSectionHeaderView {
let eventsDay = events.eventsDays[indexPath.section]
let date = DateInRegion(eventsDay.date, region: Region.current)
headerView.dayLabel.text = "\(date.weekdayName(.short).uppercased())"
headerView.dateLabel.text = "\(date.day)"
if date.isToday {
headerView.dateLabelBackgroundView.isHidden = false
headerView.dateLabel.textColor = .black
} else {
headerView.dateLabelBackgroundView.isHidden = true
headerView.dateLabel.textColor = .white
}
return headerView
}
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "EventsCalendarCollectionViewCell", for: indexPath) as! EventsCalendarCollectionViewCell
let event = events.eventsDays[indexPath.section].events[indexPath.item]
cell.dateLabel.isHidden = true
cell.configureEvent(event)
return cell
}
}
extension CalendarViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let layout = collectionViewLayout as! UICollectionViewFlowLayout
return CGSize(width: collectionView.bounds.size.width - layout.sectionInset.left - layout.sectionInset.right, height: 120)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
return CGSize(width: 48, height: 1)
}
}
extension CalendarViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
toggleCalendar(hide: true)
let event = events.eventsDays[indexPath.section].events[indexPath.item]
displayEventWithFeed(event.feed)
}
}
extension CalendarViewController: FSCalendarDelegate, FSCalendarDataSource {
func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) {
self.scrollToDate(date.date)
}
func maximumDate(for calendar: FSCalendar) -> Date {
var dateComponents:DateComponents = DateComponents()
dateComponents.month = 12
let currentCalander:Calendar = Calendar.current
return currentCalander.date(byAdding:dateComponents, to: Date())!
}
func minimumDate(for calendar: FSCalendar) -> Date {
var dateComponents:DateComponents = DateComponents()
dateComponents.month = 0
let currentCalander:Calendar = Calendar.current
return currentCalander.date(byAdding:dateComponents, to: Date())!
}
}
For creating FSCalendar programmatically and Customize

khirish
- 537
- 1
- 7
- 9