FUICalendarView

FUICalendarView control extends UIView and provides APIs to add calendar functionality in your app with minimal effort. There are five variations of FUICalendarView, as specified by the FUICalendarStyle enum-based data display and selection options.

Month

Calendar View

This is the default view with vertical scrolling enabled. It shows the dates for one entire month at a time, where, upon a scrolling action, the previous or next month is displayed on the screen based on the scroll direction.

The dates for the month are arranged in 7 columns (with a view above denoting the corresponding weekdays), spanning a maximum of five or six rows, based on the order of the first day of the week shown in the view displayed above and the total number of days in the month.

The first day of the week can be set to either Sunday, Monday, or Saturday while instantiating the calendar. In addition to showing the dates for the particular month, some dates from the previous month and the next month are also displayed, but appear in a grayed-out font color to differentiate them from the current month dates.

The previous month dates are displayed in the beginning of the first row and the next month dates appear on the last row. For example, if the month starts on a Wednesday and the weekday display view shows the day of week starting from Sunday, then in the very first row of the month being displayed, the previous month dates are shown from Sunday to Tuesday.

If the month ends on a Friday, then the remaining dates in that row (for Saturday and Sunday) denote the dates of the next month. Only one date can be selected at any time. The default selection behavior is that the first date of every month is automatically selected when the month is displayed.

If the month contains today’s date, then the current date shows selected instead. When the user clicks on another date, then that date appears selected. When isPersistentSelection is set to true, the selection behavior is different from the default selection behavior, where no date appears selected when the calendar is initially displayed (unless the developer has set a selected date using the selectDate: API). When the user selects a date, that date stays selected regardless of scrolling to another month. In both the isPersistentSelection and default mode, the developer can force a date to be selected at calendar startup by calling the selectDate: API for month, week, expandable and datesSelection styles) or selectDateRange: API for rangeSelection style.

Week

Calendar View

This view shows a single row of dates on the screen with 7 columns, one for each day of the week. This view incorporates horizontal scrolling, where the user can scroll left or right, displaying the set of dates for the particular week being displayed. In this mode, the previous month dates are displayed only for the very first month in the entire calendar range.

The default selection behavior is that the first date of every month is automatically selected, and if the user chooses another date then that date appears selected. In addition, when the user scrolls, in the next set of 7 dates shown after the scroll, the date corresponding to the day of the week of the previously selected date appears automatically selected. For example, if the user selects date 22 of the month and it falls on a Wednesday, then after a forward scroll, date 29 is selected since it will be the next Wednesday.

If isPersistentSelection is set to true, then when the user selects a date, that date stays selected regardless of scrolling. In both the isPersistentSelection and default mode, the developer can force a date to be selected at calendar startup or after a scroll by calling the selectDate: or selectDateRange: API , after calendar init or from within the calendarView(_:didChangeVisibleDatesTo:) delegate.

Expandable

Calendar View

Calendar View

This view is a combination of month and week styles. The user can toggle between the two modes using a handle that animates the transition between the modes.

rangeSelection

Calendar View

This view displays the dates similar to the month style, but takes the entire screen space. Therefore, dates for more than one month can be displayed at a time. Also, this view allows the user to select a contiguous range of dates. isPersistentSelection is always set to true and the selected dateRange stays selected regardless of scrolling to another month. The first date selected is the startDate of the range and when a second date is selected it becomes the end date of the range, with the entire range of dates between the start and end dates (inclusive) being selected. To modify the set of selected dates, click on a selected date within the range and it becomes the new end date with all the dates later than that getting deselected. To unselect the entire range, click outside the range, anywhere in the calendar view. The end range of the range must be a later date than the start date. If the user clicks on a date earlier than the start date, then the newly selected date now becomes the start date and the original start date is deselected.

datesSelection

Calendar View

Similar to rangeSelection, this style takes the entire screen space. However, it differs from the rangeSelection in how the dates are selected, allowing for the selection of multiple noncontiguous dates. It also provides a swipeToSelect functionality, where swiping across the screen would select or deselect the corresponding dates at that location.

The FUICalendar can be instantiated to display in any one of the above display modes. In addition, the developer can specify the start and end dates of the entire calendar range and the displayDateAtStartup at startup. If the start, end, and display dates are nil, that is, the user does not supply any values for those parameters, then the calendar is instantiated with a two-year range from Jan 1st of the current year to Dec 31st of the next year and the display date on startup is set to the current date.

The user can also choose to provide only the start date, end date, or display date. If the start and end dates are provided, then set up the range accordingly. If no display date is provided in this case, and if the current date falls in-between this provided range, then the calendar shows the current date on startup, otherwise the start date is displayed on startup. If only the display date is provided, then the range is from Jan 1st of the year of the displayDate to Dec 31st of next year.

Theming

FUICalendarView Theming

fdlFUICalendarView_property {}

Supported monthHeaderText properties:

font-color: Color;
font-size: Size;
font-style: UIFontTextStyle;
font-name: FontName;

FUICalendarItemView Theming

fdlFUICalendarItemView_property {}

Supported title properties:

font-color: Color;
font-size: Size;
font-style: UIFontTextStyle;
font-name: FontName;
tint-color { -disabled }: Color; // Title text color for dates that are out of current range.
tint-color { -highlighted }: Color; // Title text color for Today.
tint-color { -selected }: Color; // Title text color for selected days.

font-name { -highlighted }: FontName; // Title text for Today.
font-name { -selected }: FontName; // Title text for selected days.

Supported weekNumberText properties:

font-color: Color;
font-size: Size;
font-style: UIFontTextStyle;
font-name: FontName;

Supported selectionSingle, selectionRange properties:

background-color: Color; // Color for Views when selected.

Supported eventView properties:

background-color: Color; // The color of the eventView displayed below each date.

FUIWeekLabelView Theming

fdlFUIWeekLabelView_property {}

Supported weekDayText properties:

font-color: Color;
font-size: Size;
font-style: UIFontTextStyle;
font-name: FontName;

tint-color { -highlighted }: Color; // Title text color for Today.

// Sample view controller implementing the FUICalendarView control

private let formatter:DateFormatter = {
let dateformatter = DateFormatter()
dateformatter.timeZone = Calendar.current.timeZone
dateformatter.locale = Calendar.current.locale
dateformatter.dateFormat = "yyyy MM dd"
return dateformatter
}()

class CalendarMonthViewController: UIViewController, FUICalendarViewDelegate {

var calendarView = FUICalendarView() // initializes in the default month mode and shows the current date on startup

override func viewDidLoad() {
super.viewDidLoad()

self.viewRespectsSystemMinimumLayoutMargins = false
self.view.backgroundColor = .white
self.view.addSubview(calendarView )
calendarView.delegate = self

calendarView.translatesAutoresizingMaskIntoConstraints = false
calendarView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 0).isActive = true
calendarView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 0).isActive = true
calendarView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: 0).isActive = true

let dt = formatter.date(from:"2019 01 23")
calendarView.selectDate(dt!)
}

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
}

// Implement the FUICalendarViewDelegate methods

// Implement this method to set the title of the controller.
// This method is called whenever there is a change in the status, for example, upon each scroll, the title is updated to the current month being displayed. When a
// date is selected, then the title is updated to denote the corresponding month.
func  calendarView(_ calendarView: FUICalendarView, didChangeTitleTo title: String) {
self.navigationItem.title = title
}


// Called when there is a change in the selected dates
func  calendarView(_ calendarView: FUICalendarView, didChangeSelections selections: [FUIDateSelection]) {

}

// Called after a scrolling action
func  calendarView(_ calendarView: FUICalendarView, didChangeVisibleDates visibleDates: FUIVisibleDates) {

}

// Called when a cell (displaying the date) is selected.
func calendarView(_ calendarView: FUICalendarView, didSelectCell: FUICalendarItemCollectionViewCell, at: Date) {

}

// Called when a cell (displaying the date) is deselected.
func calendarView(_ calendarView: FUICalendarView, didDeselectCell: FUICalendarItemCollectionViewCell, at: Date) {

}

// Called before a cell (displaying the date) is displayed.
func calendar(_ calendarView: FUICalendarView, willDisplay cell: FUICalendarItemCollectionViewCell, forItemAt date: Date, indexPath: IndexPath) {

}

}

Attention

The delegate object with type FUICalendarViewDelegate is declared as a weak reference. On deallocation it will be automatically set to nil. To keep it alive as expected, developer should retain the delegate object during its whole execution scope.

  • The view that contains the weekday title labels.

    Declaration

    Swift

    public private(set) var weekLabelView: FUIWeekLabelView { get }
  • The custom background color for the calendar.

    The default is nil, meaning that the default background color is used.

    Declaration

    Swift

    open var customCalendarBackgroundColor: UIColor? { get set }
  • The calendar style.

    Declaration

    Swift

    public internal(set) var style: FUICalendarStyle { get }
  • The start day of the calendar.

    Declaration

    Swift

    public internal(set) var startDay: FUIWeekStartDay { get }
  • The title displaying the current visible month and year of the calendar.

    Declaration

    Swift

    public internal(set) var title: String { get }
  • The start date of the calendar.

    Declaration

    Swift

    public internal(set) var startDate: Date? { get }
  • The end date of the calendar.

    Declaration

    Swift

    public internal(set) var endDate: Date? { get }
  • The current visible dates of the calendar.

    Declaration

    Swift

    public internal(set) var visibleDates: FUIVisibleDates? { get }
  • The current selected dates of the calendar.

    Declaration

    Swift

    public internal(set) var selectedDates: [Date]? { get }
  • The display date at startup.

    For example, if the calendar range starts from Jan 1, 2018 and the developer would like to show the month of June when the calendar starts up, then the displayDateAtStartup needs to be set to June 1, 2019.

    Declaration

    Swift

    public internal(set) var displayDateAtStartup: Date? { get }
  • The color of the view displayed upon selection of a date.

    Declaration

    Swift

    public var selectionSingleColor: UIColor?
  • The color of the view displayed upon a range selection of dates

    Declaration

    Swift

    public var selectionRangeColor: UIColor?
  • The color of the eventView displayed below each date.

    Declaration

    Swift

    public var eventViewColor: UIColor?
  • Boolean indicates whether or not the calendar displays the event indicator.

    If set to false, the calendar will not show the event indicator, regardless of whether the date has events or not.

    The value cannot be changed after it is set during initialization of the FUICalendarView.

    Declaration

    Swift

    public internal(set) var hasEventIndicator: Bool { get set }
  • The FUICalendarView delegate.

    Declaration

    Swift

    public weak var delegate: FUICalendarViewDelegate? { get set }
  • Boolean indicates whether or not a selected date stays selected when the user scrolls away to another set of dates.

    The default is false for month, week, and expandable styles except for rangeSelection and datesSelection styles, which is always true (hence, if the developer sets isPersistentSelection to false, it will have no effect).

    In month style, the default behavior is that the first date of every month is selected when the month is displayed. (If the particular month contains today’s date, then it is selected instead.) Also, the selection is not persistent. For example, on startup of the calendar, assume that January is displayed with Jan 1st selected. Then, if a user clicks on another date, for example Jan 25th, it is selected now. If the user then scrolls to Feb, then Feb 1st shows as selected. Scrolling back to January, the 1st of January is selected now and not the 25th as the user had previously selected.

    In the case where isPersistentSelection is true, then the behavior is as follows: No date is selected when the calendar is displayed or scrolled to another month, except if a date was set by the selectDate: (for month, week, expandable, and datesSelection) or selectDateRange:(for multipleSelection View) by the developer. When the user then selects another date, then this date is now selected, regardless of whether the user scrolls to any other month.

    The value cannot be changed after it is set during initialization of the calendarView.

    Declaration

    Swift

    public internal(set) var isPersistentSelection: Bool { get set }
  • This property indicates if the calendar view also shows the week number of not.

    The default is false.

    Declaration

    Swift

    public var showsWeekNumbers: Bool
  • This property indicates whether the month header is to be displayed for the fullScreenMonth style calendar.

    The default is false, meaning that the month header will not be displayed. This property is only valid for the fullScreenMonth style.

    Declaration

    Swift

    public var showsMonthHeader: Bool { get set }
  • The maximum height for this FUICalendarView.

    If this is property is set, the height of the date cell will be adjusted. However, the height of the date cell will be limited to a minimum of 44 px and a maximum of 51 px.

    The default is nil and the default 51 px date cell height is used.

    Declaration

    Swift

    public var maximumViewHeight: CGFloat? { get set }
  • The FUITintAttributesProvider for calendar items.

    Developers can use this property to customize the tint attributes of the calendar items. When setting the title text displaying the dates, use ‘.normal’ state for all unselected dates, ‘.selected’ for a selected date, and ‘.highlighted’ for the current date. In the case of month style, to display the previous and next month dates for every month in a different color other than the current month dates, use ‘.disabled’ state.

    // Customize the `weekNumber` Text properties
    calendarView.calendarItemTintAttributesProvider.setAttributes([NSAttributedString.Key.foregroundColor: UIColor.green], for: .weekNumberText, state: .normal)
    // Customize the title Text properties.
    // To set the month dates' color
    calendarView.calendarItemTintAttributesProvider.setAttributes([NSAttributedString.Key.foregroundColor: UIColor.blue], for: .title, state: .normal)
    // To set the color of previous and next month dates
    calendarView.calendarItemTintAttributesProvider.setAttributes([NSAttributedString.Key.foregroundColor: UIColor.yellow], for: .title, state: .enabled)
    // To set the selected date color
    calendarView.calendarItemTintAttributesProvider.setAttributes([NSAttributedString.Key.foregroundColor: UIColor.red], for: .title, state: .selected)
    // To set the current date color if it is displayed
    calendarView.calendarItemTintAttributesProvider.setAttributes([NSAttributedString.Key.foregroundColor: UIColor.green], for: .title, state: .highlighted)
    // To set the disabled date color if it is displayed
    calendarView.calendarItemTintAttributesProvider.setAttributes([NSAttributedString.Key.foregroundColor: UIColor.green], for: .title, state: .disabled)
    // To set the `monthHeader` color
    calendarView.calendarItemTintAttributesProvider.setAttributes([NSAttributedString.Key.foregroundColor: UIColor.green], for: .monthHeaderText, state: .normal)
    // To set the week label title color
    calendarView.calendarItemTintAttributesProvider.setAttributes([NSAttributedString.Key.foregroundColor: UIColor.blue], for: .weekDayText, state: .normal)
    // To set the current day to a different color in the `weeklabel` title if the current date is displayed in the visible month.
    calendarView.calendarItemTintAttributesProvider.setAttributes([NSAttributedString.Key.foregroundColor: UIColor.green], for: .weekDayText, state: .highlighted)
    

    Declaration

    Swift

    public let calendarItemTintAttributesProvider: FUIControlStateTintAttributesProvider
  • The disabled dates.

    The default is nil, which means all displayed dates are selectable.

    Declaration

    Swift

    public var disabledDates: FUICalendarDisabledDates?
  • The type of secondary calendar to be displayed.

    The default is .none, meaning that there is no secondary calendar to be displayed.

    Declaration

    Swift

    public var alternateCalendar: FUIAlternateCalendar
  • The Locale to be used for alternate calendar.

    The default is nil which means the corresponding default Locale for the secondary calendar is used.

    Declaration

    Swift

    public var alternateCalendarLocale: Locale?
  • Initialize the FUICalendarView instance

    Declaration

    Swift

    public init(calendarStyle: FUICalendarStyle = .month, weekStartDay: FUIWeekStartDay = .localeSpecific, startDate: Date? = nil, endDate: Date? = nil, displayDateAtStartup: Date? = nil, isPersistentSelection: Bool = false, hasEventIndicator: Bool = true, expandableStyleStartsWithWeek: Bool = false)

    Parameters

    calendarStyle

    The FUICalendarView instance.

    weekStartDay

    The start day enum that denotes the first letter of the display label denoting the days of the week.

    startDate

    The start date of the calendar.

    endDate

    The end date of the calendar.

    displayDateAtStartup

    The display date at startup.

    isPersistentSelection

    Specifies if the selection is persistent.

    hasEventIndicator

    Specifies if the event indicator view is displayed.

    expandableStyleStartsWithWeek

    This boolean parameter indicates whether to start with week view if calendarStyle is .expandable. The default is false, meaning that it starts with the month view for expandable style. This parameter is ignored if calendarStyle is not .expandable.

  • Scrolls the calendar view to the start of a section view containing a specified date.

    Declaration

    Swift

    open func scrollToDate(_ date: Date?, animated: Bool = true, completionHandler: (() -> Void)? = nil)
  • Selects a single date. This API is for the month, week, expandable, and datesSelection styles only.

    If a ‘nil’ value is passed for the date, then any current date that is selected is deselected.

    Declaration

    Swift

    open func selectDate(_ date: Date?, triggersDelegateCall: Bool = true)

    Parameters

    date

    The date to select. The selected dates will not change if a disabled date is specified.

    triggersDelegateCall

    Triggers invocation of the didSelectDate delegate function call when actual selection occurs. The default is true.

  • Selects a date range. This API is for the rangeSelectionView only. If nil is provided for the date range, then any selected range of dates is deselected.

    Declaration

    Swift

    open func selectDateRange(_ dateRange: FUIDateRange?)