I am using this code to add dots for events and the dots appear perfectly fine but when I select the day with the event, the dot permanently disappears and even when selecting another day, the dot still doesnt reappear.
here is my code to make the dots appear at the start
func calendar(_ calendar: FSCalendar, willDisplay cell: FSCalendarCell, for date: Date, at monthPosition: FSCalendarMonthPosition) {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let dateString = dateFormatter.string(from: date)
cell.eventIndicator.isHidden = false
for wp in worriesPanic{
let wPDateStr = dateFormatter.string(from: wp.date!)
if wPDateStr == dateString {
cell.eventIndicator.numberOfEvents = 1
break
}
}
}
You can use image method for show event.
func calendar(_ calendar: FSCalendar, imageFor date: Date) -> UIImage? {
let dateString = self.dateFormatter1.string(from: date)
if self.yourDate.contains(dateString) {
return UIImage(named:"img")
}
return nil
}
Related
In my case, I am trying to customise FSCalendar. Here, add multiple event in calendar options available but it is showing three dots. I need to do If two same date in the array need to show two dot also if three need to show three dot but above three also need to show only three dot. How to achieve this?
https://iosexample.com/a-fully-customizable-ios-calendar-library-compatible-with-objective-c-and-swift/
My Code
var datesWithEvent = ["02-09-2019", "03-09-2019", "07-09-2019", "09-09-2019"]
var datesWithMultipleEvents = ["03-09-2019", "03-09-2019", "02-09-2019", "09-09-2019"]
func calendar(_ calendar: FSCalendar, numberOfEventsFor date: Date) -> Int {
let dateString = self.dateFormatter.string(from: date)
if self.datesWithEvent.contains(dateString) {
return 1
}
if self.datesWithMultipleEvents.contains(dateString) {
return 3
}
return 0
}
func calendar(_ calendar: FSCalendar, appearance: FSCalendarAppearance, eventDefaultColorsFor date: Date) -> [UIColor]? {
let key = self.dateFormatter.string(from: date)
if self.datesWithMultipleEvents.contains(key) {
return [UIColor.magenta, appearance.eventDefaultColor, UIColor.black]
}
return nil
}
Here,Below answer for adjusting the FSCalendar dot UI count based on JSON array Data.
func calendar(_ calendar: FSCalendar, numberOfEventsFor date: Date) -> Int {
let dateString = self.dateFormatter.string(from: date)
if self.datesWithEvent.contains(dateString) {
return 1 // Here, We have to assign JSON count key value based on duplication it will increase dot count UI.
}
return 0
}
How to update date in fscalender initially while launching an app. i am updating the date while scrolling fscalender but my doubt initially loading app how to send date to Post service Call?
This is my api for getting dates from server.
let now2 = NSDate()
let dateFormatter2 = DateFormatter()
dateFormatter2.dateFormat = "yyyy"
let nameOfyear = dateFormatter2.string(from: now2 as Date)
print("nameOfyear",nameOfyear)
let urlString = Fetch_Parent_Dashboard_Calendar_URL+"&year="+nameOfyear+"&month="+nameOfMonth+"&branch_id=" + Userbranchid!
i am taking date value from user defaults sending to server when user scrolling fscalender.Following is the code for sending date to server when scrolling fscalender.
func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition)
{
let dateFormatter2 = DateFormatter()
dateFormatter2.dateFormat = "dd/MM/yyyy"
let nameOfDate = dateFormatter2.string(from: date as Date)
print("nameOfDate",nameOfDate)
UserDefaults.standard.set(nameOfDate, forKey: "nameOfDate")
}
My doubt is initially loading the app i have to send current date and scrolling time have to send that user defaults time how to handle date at this case
If i understood correctly you have to do like this.
Make generic function to call web service with the given date
func callWebServiceWithDate(date:Date)
{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy"
let nameOfyear = dateFormatter.string(from: date)
dateFormatter.dateFormat = "MM"
let nameOfMonth = dateFormatter.string(from: date)
let urlString = Fetch_Parent_Dashboard_Calendar_URL+"&year="+nameOfyear+"&month="+nameOfMonth+"&branch_id=" + Userbranchid!
}
Now call this method from viewDidLoad or viewWillAppear method with Date() as input parameter for initial call.
override func viewDidLoad()
{
super.viewDidLoad()
self.callWebServiceWithDate(date: Date())
}
And call the same method from FSCalendars delegate method
func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition)
{
self.callWebServiceWithDate(date: date)
}
I have a calendar, and I want to select an entire row (week) when I select a day.. this is my code so far:
//When a date is selected
func calendar(_ calendar: JTAppleCalendarView, didSelectDate date: Date, cell: JTAppleCell?, cellState: CellState) {
selectTheWeek(of: date)
setupLayoutCell(cell: cell, cellState: cellState)
}
func selectTheWeek(of date: Date) {
let starOfTheWeek = date.startOfWeek()
let endOfTheWeeK = date.endOfWeek()
calendarCollectionView.selectDates(from: starOfTheWeek, to: endOfTheWeeK)
}
extension Date {
func startOfWeek() -> Date {
let calendar = Calendar.autoupdatingCurrent
let currentDateComponents = calendar.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self)
return calendar.date(from: currentDateComponents)!
}
func endOfWeek() -> Date {
let cal = Calendar.autoupdatingCurrent
var component = DateComponents()
component.weekOfYear = 1
component.day = -1
return cal.date(byAdding: component, to: startOfWeek())!
}
}
the problem is that I'm having an infinite loop, and it's clear the reason.
But I don't know how to prevent it. Any help?
JTAppleCalender is an external library. It's an extension of a collectionView.
You can use 2 techniques to break the loop.
First:
calendarViewselectDates(from: starOfTheWeek, to: endOfTheWeeK, triggerSelectionDelegate: false)
By setting triggerSelectionDelegate to false, your delegate function didSelect will not be called.
Second:
If you are using MasterBranch code (which i'll be releasing in a week or so), you can know whether or not your selection is programmer initiated vs user initiated. You know this by --> cellState.
if cellState.selectionType == .programatic {
// ignore stuff
} else {
// Do stuff
}
You can put this if statement in your shouldSelect function.
I know this is a not the best possible solution but it could work to avoid your issue
//When a date is selected
var shouldSelectWeek = true
func calendar(_ calendar: JTAppleCalendarView, didSelectDate date: Date, cell: JTAppleCell?, cellState: CellState) {
if shouldSelectWeek{
selectTheWeek(of: date)
shouldSelectWeek = false
}
setupLayoutCell(cell: cell, cellState: cellState)
}
func selectTheWeek(of date: Date) {
let starOfTheWeek = date.startOfWeek()
let endOfTheWeeK = date.endOfWeek()
calendarCollectionView.selectDates(from: starOfTheWeek, to: endOfTheWeeK)
}
extension Date {
func startOfWeek() -> Date {
let calendar = Calendar.autoupdatingCurrent
let currentDateComponents = calendar.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self)
return calendar.date(from: currentDateComponents)!
}
func endOfWeek() -> Date {
let cal = Calendar.autoupdatingCurrent
var component = DateComponents()
component.weekOfYear = 1
component.day = -1
return cal.date(byAdding: component, to: startOfWeek())!
}
Just add a new boolean variable like var shouldIgnoreDateSelection = false and then you just do
func calendar(_ calendar: JTAppleCalendarView, didSelectDate date: Date, cell: JTAppleCell?, cellState: CellState) {
if shouldIgnoreDateSelection == false {
selectTheWeek(of: date)
}
setupLayoutCell(cell: cell, cellState: cellState)
}
func selectTheWeek(of date: Date) {
let starOfTheWeek = date.startOfWeek()
let endOfTheWeeK = date.endOfWeek()
shouldIgnoreDateSelection = true
calendarCollectionView.selectDates(from: starOfTheWeek, to: endOfTheWeeK)
shouldIgnoreDateSelection = false
}
I'm using fs calendar and i'm trying to set event dots from an array named dates. this array has event dates in it that are saved in string form. so i have to convert each index to date and then set an event dot for that date.
here is my attempt to do so:
if dates.isEmpty == false {
func calendar(_calendar: FSCalendar!, hasEventForDate dateFormatter: DateFormatter) -> Bool {
for i in 0...dates.count - 1 {
let dateFormatter = DateFormatter ()
dateFormatter.dateFormat = "yyyy/MM/dd"
dateFormatter.locale = Locale.init(identifier: "fa_IR")
dateFormatter.date(from: dates[i])
dateFormatter.dateFormat = "yyyy/MM/dd"
return true
}
return false
}
}
but nothing happens and there is no event dot when i compile the code. what am i doing wrong?
First recommendation, use a dictionary instead of array of dates, is less demanding to lookup dates in a dictionary
Second if you need use values in an array then you should use for in and use objects directly, not index to get objects in the original array, also declare the date formatter only once
Third you need use func calendar(_ calendar: FSCalendar, numberOfEventsFor date: Date) -> Int because func calendar(_calendar: FSCalendar!, hasEventForDate dateFormatter: DateFormatter) -> Bool is deprecated
Try with this code
func calendar(_ calendar: FSCalendar, numberOfEventsFor date: Date) -> Int {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy/MM/dd"
dateFormatter.locale = Locale.init(identifier: "fa_IR")
for dateStr in dates{
if(dateFormatter.string(from: date) == dateStr)
{
return 1
}
}
return 0
}
I am using FSCalendar to add calendar UI in my project . But I am unable to find any solution to add events to the calendar. So any ideas on how to add events to FSCalendar or any third party calendar framework?
To Set Events Base On Dates..
Instance of DateFormatter And Variables:
var datesWithEvent = ["2015-10-03", "2015-10-06", "2015-10-12", "2015-10-25"]
var datesWithMultipleEvents = ["2015-10-08", "2015-10-16", "2015-10-20", "2015-10-28"]
fileprivate lazy var dateFormatter2: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
next is... DataSource Function:
func calendar(_ calendar: FSCalendar, numberOfEventsFor date: Date) -> Int {
let dateString = self.dateFormatter2.string(from: date)
if self.datesWithEvent.contains(dateString) {
return 1
}
if self.datesWithMultipleEvents.contains(dateString) {
return 3
}
return 0
}
I Hope This Help You, This Code is Base On FsCalendar Sample Project.
I have an array that contains events's dates and the number of event on this date what I did is:
1- Comparing dates(comparing dates without time using compareDate(data.eventDate!, toDate: date, toUnitGranularity: .Day)) from my array with date(in the function)
2- If they're equal I'll add date to an array(datesWithEvent) without time so I can compare it later without problems
3- return true when it finds the right dates
var datesWithEvent:[NSDate] = []
func calendar(calendar: FSCalendar, hasEventForDate date: NSDate) -> Bool {
for data in eventsArray{
let order = NSCalendar.currentCalendar().compareDate(data.eventDate!, toDate: date, toUnitGranularity: .Day)
if order == NSComparisonResult.OrderedSame{
let unitFlags: NSCalendarUnit = [ .Day, .Month, .Year]
let calendar2: NSCalendar = NSCalendar.currentCalendar()
let components: NSDateComponents = calendar2.components(unitFlags, fromDate: data.eventDate!)
datesWithEvent.append(calendar2.dateFromComponents(components)!)
}
}
return datesWithEvent.contains(date)
}
And to precise the number of event on this date (different number of dots) I've added this code
func calendar(calendar: FSCalendar, numberOfEventsForDate date: NSDate) -> Int {
for data in eventsArray{
let order = NSCalendar.currentCalendar().compareDate(data.eventDate!, toDate: date, toUnitGranularity: .Day)
if order == NSComparisonResult.OrderedSame{
return data.numberOfEvent!
}
}
return 0
}
Try this code,in Objective-C
- (NSInteger)calendar:(FSCalendar *)calendar numberOfEventsForDate:(NSDate*)date
{
NSString *dateString = [calendar stringFromDate:date format:#"yyyy-MM-dd"];
if ([_datesWithEvent containsObject:dateString]){
return 1;
}
else{
NSLog(#"........Events List........");
}
return 0;
}
try these code it will help you
func calendar(_ calendar: FSCalendar, numberOfEventsFor date: Date) -> Int {
let dateString = self.dateFormatter.string(from: date)
print(dateString)
// datesForEvents : array of dates
if self.datesForEvents.contains(dateString) {
return 1
}
return 0