Hi,
im using JTAppleCalendar to show all events of all ios calendars inside my app. In the app the users should be able to scroll to next and previous month without maximum range (like it is in the apple ios calendar). For now my plan was the following:
extension CalendarViewControllerModeMonth : JTAppleCalendarViewDataSource {
func configureCalendar(_ calendar: JTAppleCalendarView) -> ConfigurationParameters {
let dateStart = (self.currentDate.adding(months: -2)?.startOfDay())!;
let dateEnd = (self.currentDate.adding(months: 2)?.endOfDay())!;
let parameters = ConfigurationParameters(startDate: dateStart, endDate: dateEnd, numberOfRows: 6, calendar: Calendar.current, generateInDates: .forAllMonths, generateOutDates: .tillEndOfGrid, firstDayOfWeek: .monday);
return parameters;
}
}
override func setupCalendar() {
let first = (self.currentDate.adding(months: -2)?.startOfMonth())!;
let last = (self.currentDate.adding(months: 2)?.endOfMonth())!;
let appointments = CalendarApple.getAppointments(startDate: first, endDate: last);
self.viewCalendar.selectDates([self.currentDate]);
self.viewCalendar.reloadData();
self.viewCalendar.scrollToDate(self.currentDate, triggerScrollToDateDelegate: false, animateScroll: false);
}
func calendar(_ calendar: JTAppleCalendarView, didScrollToDateSegmentWith visibleDates: DateSegmentInfo) {
self.currentDate = visibleDates.monthDates.first!;
self.setupCalendar();
}
So that makes it possible to infinitly scrolling backward and forward without having to initialize the calendar with more than 5 months at the same time. This saves memory and also cpu usage (for the synchronisation between apple calendar and app calendar).
It works!
But there is one small thing: Ofcourse the view is getting redrawn after each scroll because the calendar is getting initialized with a new range. So there is a small but clearly visible and annoying flickering after each scroll.
Do you have an idea how I could solve it or another way to get working what im trying to do?
Oh... It seems to be fixed when I choose a bigger range. If I use to create months from -3 to +3 the flickering is gone.
hmm. this is an interesting implementation. Can you let me know the number of rows your are displaying in your calendar? And also, are you displaying inDates and outDates as well?
Hi,
im displaying whole months with inDates and outDates.
It works perfectly when I set the range from 2 up to 3 +/-:
extension CalendarViewControllerModeMonth : JTAppleCalendarViewDataSource {
func configureCalendar(_ calendar: JTAppleCalendarView) -> ConfigurationParameters {
let dateStart = (self.currentDate.adding(months: -3)?.startOfDay())!;
let dateEnd = (self.currentDate.adding(months: 3)?.endOfDay())!;
let parameters = ConfigurationParameters(startDate: dateStart, endDate: dateEnd, numberOfRows: 6, calendar: Calendar.current, generateInDates: .forAllMonths, generateOutDates: .tillEndOfGrid, firstDayOfWeek: .monday);
return parameters;
}
}
override func setupCalendar() {
let first = (self.currentDate.adding(months: -3)?.startOfMonth())!;
let last = (self.currentDate.adding(months: 3)?.endOfMonth())!;
let appointments = CalendarApple.getAppointments(startDate: first, endDate: last);
self.viewCalendar.selectDates([self.currentDate]);
self.viewCalendar.reloadData();
self.viewCalendar.scrollToDate(self.currentDate, triggerScrollToDateDelegate: false, animateScroll: false);
}
func calendar(_ calendar: JTAppleCalendarView, didScrollToDateSegmentWith visibleDates: DateSegmentInfo) {
self.currentDate = visibleDates.monthDates.first!;
self.setupCalendar();
}
Its really smoothly and also really nice to not have such a huge range (100 or more years) preloaded but still being able to scroll to each month and year.
Thanks.
I will mention this approach to others when needed.
I'll change the title of thie issue so that i can remember it.
@patchthecode
As you can see in @Montrazul's setupCalendar() function, he calls selectDates() before reloadData(). When I do that I don't get the flicker when scrolling to a different section even if I only load 2 extra months at a time. The problem is that calling selectDates() first causes the reloading to cut my date selection animations, and if I don't call it I get those flickers. I don't understand why this happens.
Also if in configureCalendar I print the startDate and endDate before returning the ConfigurationParameters, every time I scroll I see it gets printed twice, so the configureCalendar function is called twice for some reason, even if I only call reloadData() once on didScrollToDateSegmentWith visibleDates. I don't know if this has anything to do with the first problem.
For now I can live with the animations being cut short every now and then, but it's just weird that when a cell isn't already selected reloadData() should have those flickers; reloading 4 to 6 months should be pretty fast, and I don't see what selectDate() has to do with it.
@dbmrq hmm.. i think i'll have to not put it off any longer...
i'll have to code that damn infinite scroll calendar haha.
I'll look into why it is flickering
If you got a quick app setup on github i'll take a look. Right now, i'm too tied up to create anything xD
Haha, yes, that would be great. :)
@Montrazul's approach works pretty well already, except for that annoying flickering.
If you add the infinite scrolling by default, the configureCalendar function could be completely optional, since people wouldn't have to return the start and end dates anymore. That would make JTAppleCalendar even easier to configure. You'd just have to add cellForItem and that's it.
Also this approach allows you to load just a few months at a time, so you can do harder calculations for the cell appearance without that much overhead. In my app, for instance, I have dot markers that may or may not appear at a certain date. I wanted to add different dot markers for different information, but then I had to calculate a lot of different variables for each day and on a long calendar that would take too long and the calendar would lag. Now, loading just a few months at a time, I can do all sorts of crazy stuff and it's always zippy.
I won't have the time today, but in the next couple of days I can add an example project here. :)
@dbmrq alright thanks. Will look for it. I'll think about the changes needed for inf calendar in the mean time.
PS: Maybe this will help: https://stackoverflow.com/a/29453533/3539651
@dbmrq Thanks, i will look it up. I'll make this library even better 馃憤
@patchthecode
Hey!
Apparently I wasn't using the latest version of the calendar, now I wrote a sample app and I don't get the flashes anymore. 馃嵕
The last time I updated the library was about a month ago, so you did something that fixed the problem in the last month.
What I said about configureCalendar being called twice still happens though.
Here's the example app I made: https://github.com/dbmrq/JTCalTest
If you run the version on the master branch and scroll right a few times you'll see it doesn't scroll forever. I'm trying to calculate the start and end dates on the fly with computed variables based on calendarView.visibleDates().monthDates.first?.date. The problem is that when I call reloadData() on didScrollToDateSegmentWith configureCalendar is called twice, and the second time visibleDates().monthDates.first is always nil. If you scroll through the calendar and look at the console you'll see what I mean, I added some print() statements to show it.
So that attempt of calculating the start and end dates on the fly didn't work. If you check the second-attempt branch, that one works, because instead of using computed variables based on visibleDates().monthDates.first I'm keeping a reference in a stored property. I also added a couple of steppers, so you can experiment with changing how many months are loaded at a time and how hard the app works to load them. It seems to work perfectly even when loading just 1 extra month at a time! 馃帀
So, well, the attempt on the master branch seems more elegant to me, but the other attempt works fine and the infinite scrolling is working great so far. Thanks! :)
adding related issue here -> https://github.com/patchthecode/JTAppleCalendar/issues/470
And closing this one.
Most helpful comment
Hi,
im displaying whole months with
inDatesandoutDates.It works perfectly when I set the range from 2 up to 3 +/-:
Its really smoothly and also really nice to not have such a huge range (100 or more years) preloaded but still being able to scroll to each month and year.