CalendarKit Issue with the Date Scroll Bar - Swift

1.6k views Asked by At

I've been having issues with using JT Apple Calendar to select a date to display in CalendarKit. The label will display the proper date, but the date selector above it, does not reflect the date that the label shows.

Is there an easy way to fix this? I've been told that it may be a bug.

The date scroll bar seems to take the current date, instead of the date that's been selected. I selected January 19th, 2017, but the date scroll bar shows December 2, 2017 which is today's date.

This is the package home for reference: https://github.com/richardtop/CalendarKit

enter image description here

Here is the relevant part of the code, where selectedDate is the date being displayed in the label and passed from JTAppleCalendar:

var selectedDate: Date! var selectedEvent: Event! var newEventDate: Date!

override func viewDidLoad() {
    super.viewDidLoad()

    dayView.autoScrollToFirstEvent = true
    navigationController?.navigationBar.backgroundColor = .white
    reloadData()
    loadForSelectedDate(date: selectedDate)
}


func loadForSelectedDate(date: Date) {
    dayView.state = DayViewState(date: date)
    dayView.state?.move(to: date)
    dayView.reloadData()
}
2

There are 2 answers

6
Richard Topchii On

CalendarKit uses a separate object, called DayViewState to update all of its views in a synchronized manner.

The reason why the labels on the scrollbar are not updates is that the corresponding methods on the DayViewState has not been called. Most likely, you're trying to call move(from oldDate: Date, to newDate: Date) only on one of the CalendarKit's components.

The correct way to change the date on all the elements of the DayView (Timeline, Scrollbar and TimeLabel) is to invoke this method on the DayViewState:

let date = // Get Date from JTAppleCalendar
// Set date to all the elements of the CalendarKit
dayView.state?.move(to: date)

Update on the code example

I've found a couple of cases where CalendarKit is used not the way it was intended.

I've made comments along your code snippet, to better understand how to change it:

func loadForSelectedDate(date: Date) {
    // No need to create a new state. DayView creates and configures its own state, and automatically links all the components together.
    // dayView.state = DayViewState(date: date)

    // Just call this method to move to the needed date
    dayView.state?.move(to: date)

    // No need to call `reloadData()` as the DayView will ask the DataSource automatically when the selected date is reached.
    // dayView.reloadData()
}

After all the modifications, it could be shortened to just a single line:

func loadForSelectedDate(date: Date) {
    // Just call this method to move to the needed date
    dayView.state?.move(to: date)
}

Still, your code should have worked (even when you're creating a new state), so you've definitely uncovered a bug in the library.

1
Luis Yañez On

I think that you are changing between views, because i am doing the same, and i did this: in your DayViewController use viewDidAppear instead of viewDidLoad something like this:

override func viewDidAppear(_ animated: Bool) {
    let dateJT = //your date variable from JTAppleCalendar
    dayView.state?.move(to: dateJT!)
}