Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple dates in a month are blanked out. #46

Closed
isaacthedeveloper opened this issue Aug 19, 2020 · 6 comments
Closed

Multiple dates in a month are blanked out. #46

isaacthedeveloper opened this issue Aug 19, 2020 · 6 comments
Assignees

Comments

@isaacthedeveloper
Copy link

While leaving default code, certain dates in each month are blank. When selected they are show but otherwise they are blank... this issue does not occur to other unselected dates.

@bryankeller
Copy link
Contributor

Hi @isaacthedeveloper - this happens with the default example project code, with nothing changed?

Can you please post the code to repro this issue? Thank you!

@bryankeller bryankeller self-assigned this Aug 20, 2020
@isaacthedeveloper
Copy link
Author

isaacthedeveloper commented Aug 20, 2020

Hi @bryankeller Thank you for getting back so quickly! Here is the code and some screenshots.

` private func makeContent() -> CalendarViewContent {
let startDate = gregorian.date(from: DateComponents(year: 2020, month: 01, day: 01))!
let endDate = gregorian.date(from: DateComponents(year: 2031, month: 12, day: 31))!

  return CalendarViewContent(
    calendar: gregorian,
    visibleDateRange: startDate...endDate,
    monthsLayout: .horizontal(monthWidth: self.calendarContainerView.bounds.width - 64))
    .withInterMonthSpacing(32)
    .withDayItemProvider { day in
        let isSelected = day == self.selectedDay

        return CalendarItem<DayView, Day>(
            viewModel: day,
            styleID: isSelected ? "Selected" : "Default",
            buildView: { DayView(isSelectedStyle: isSelected) },
            updateViewModel: { [weak self] dayView, day in
                guard let self = self else { return }

                dayView.dayText = "\(day.day)"

                let date = self.gregorian.date(from: day.components)
                let today = self.gregorian.date(from: self.gregorian.dateComponents([.year, .month, .day], from: Date())) ?? Date()
                let hasEvents = self.getCalendarDay(by: date ?? Date()) != nil
                dayView.hasEvents = hasEvents
                dayView.isToday = date == today

                if let date = self.gregorian.date(from: day.components) {
                    dayView.dayAccessibilityText = self.formatter.string(from: date)
                } else {
                    dayView.dayAccessibilityText = nil
                }
            },
            updateHighlightState: { dayView, isHighlighted in
                dayView.isHighlighted = isHighlighted
        })
    }
}`

Photo 1 shows the 14th on the month blank, then shown once selected on photo 2.
Photo 3 has the fifth of the month blanked out, but photo 4 shows the fifth of the month selected.

Screen Shot 2020-08-20 at 11 41 34 AM
Screen Shot 2020-08-20 at 11 41 45 AM
Screen Shot 2020-08-20 at 11 41 58 AM
Screen Shot 2020-08-20 at 11 42 07 AM

@bryankeller
Copy link
Contributor

Thanks for the sample code, @isaacthedeveloper !

The problem here is that your updateViewModel implementation is making changes to the view without using the viewModel property.

let hasEvents = self.getCalendarDay(by: date ?? Date()) != nil
dayView.hasEvents = hasEvents
dayView.isToday = date == today

HorizonCalendar has no way of tracking these changes, since from its perspective, your viewModel has not changed and therefore your view does not need to be updated.


To fix this, you should create a new type to represent all of the state for your DayView. Something like this:

struct DayViewModel: Equatable {
  let day: Day
  let hasEvents: Bool
  let isToday: Bool
}

Then, change your CalendarItem type to CalendarItem<DayView, DayViewModel>.

Make sure you don't do any extra view configuration in updateViewModel, otherwise HorizonCalendar will not know about the changes. I'm currently working on some API changes that will make this much less error-prone 🙂

@bryankeller
Copy link
Contributor

Also note that #29 is the same issue, and has more details / discussion. Cheers!

@bryankeller
Copy link
Contributor

@isaacthedeveloper version 1.4.0 makes it much harder to introduce bugs like this. Check out the updated README.md and example project to see how to use the new API 🙂

@isaacthedeveloper
Copy link
Author

@bryankeller thank you so much for the help, really appreciate it :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants