iosswiftuicalendarview

In UICalendarView, can we have multiDateSelection but disable user selection?


In UICalendarView, I want to set the calendar up with some pre-defined selected dates. I don't want the user to be able to select any more or deselect any dates. But we don't want the dates to be grayed out. Here's what I have done:

  1. To set up the pre-defined selected dates, I did this. This works as intended - the selected dates in my database are selected on the calendarView.
let multiDateSelection = UICalendarSelectionMultiDate(delegate: self)
multiDateSelection.selectedDates = myDatabase.selectedDates()
calendarView.selectionBehavior = multiDateSelection
  1. In the UICalendarSelectionMultiDateDelegate, I set canSelectDate and canDeselectDate to return false. This disables the user's ability to select and deselect the dates. However, this causes the dates to become grayed out, which I don't want.
 func multiDateSelection(_ selection: UICalendarSelectionMultiDate, canSelectDate dateComponents: DateComponents) -> Bool {
        return false
    }
    
    func multiDateSelection(_ selection: UICalendarSelectionMultiDate, canDeselectDate dateComponents: DateComponents) -> Bool {
        return false
    }

Also, we can't set:

calendarView.isUserInteractionEnabled = false

as that disables swiping horizontally on the view.

Is there a way to have some predefined dates appear as selected on the calendarView, but disable the user's ability to select/deselect any more? Thank you


Solution

  • Setup the multi-date selection delegate so any date can be selected, no date can be deselected, and when a date is selected you deselect it. This gives the user the ability to scroll around the calendar, see the pre-selected dates, but it prevents them from changing those selections.

    func multiDateSelection(_ selection: UICalendarSelectionMultiDate, canSelectDate dateComponents: DateComponents) -> Bool {
        return true // This avoids any dates being grayed out
    }
    
    func multiDateSelection(_ selection: UICalendarSelectionMultiDate, canDeselectDate dateComponents: DateComponents) -> Bool {
        return false // Don't let the user deselect the pre-selected dates
    }
    
    func multiDateSelection(_ selection: UICalendarSelectionMultiDate, didSelectDate dateComponents: DateComponents) {
        // If the user does select any date, turn around and deselect it
        var selected = selection.selectedDates
        selected.removeAll { $0 == dateComponents }
        selection.setSelectedDates(selected, animated: false)
    }
    
    func multiDateSelection(_ selection: UICalendarSelectionMultiDate, didDeselectDate dateComponents: DateComponents) {
        // no-op since we don't allow any deselection
    }