# KVKCalendar: a Swift calendar built from five swappable view modules

> KVKCalendar is an MIT licensed Swift library for Apple platforms that renders day, week, month, year and event list calendars from data you supply. It wins on customisation and loses on everything it deliberately leaves to you, including the event store.

**kvyatkovskys/KVKCalendar** — A most fully customization calendar for Apple platforms 📅

- Repository: https://github.com/kvyatkovskys/KVKCalendar
- Website: https://kvyatkovskys.github.io/KVKCalendar/
- Stars: 807 · Forks: 135
- Language: Swift
- License: MIT
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/kvyatkovskys-kvkcalendar

## Five view modules share one event array

KVKCalendar is not a single calendar widget. The library is organised as five modules for displaying different calendar types: day, week, month, year and a list of events. The documentation states you can choose any one module or use all of them, and the topic list on the repository matches that split with entries such as `ios-calendar`, `timeline` and `timeline-library`. The timeline module handles the schedule view for a single day and for a week.

The important design decision is that all five modules sit on top of the same data contract, so an event model written once renders everywhere. There is also an event list mode for weekly viewing, which is the mode you want when a week of items does not fit into columns. Multiple Windows support on iPad is listed as a completed feature, and the ability to configure the frame used when viewing events is tied to a specific pull request in the repository.

For a team shipping a scheduling feature, that module split is the point of the library. The cost is that you are committing to a UI layer with its own cell, header and event view classes, and those classes are the surface you will be subclassing for the life of your app.

## Events arrive through CalendarDataSource, not from a built in store

KVKCalendar has no database and no sync layer. Events are handed to the library by the app, and the documented pattern is to build an array of `Event` objects and return it from the data source. The sample maps incoming models with `compactMap`, setting an identifier, a start and end date, a colour, an all day flag, a file presence flag, a recurring type and the display text.

```swift
import KVKCalendar
final class KVKCalendarVC: UIViewController {
    var events = [Event]()
    override func viewDidLoad() {
        super.viewDidLoad()
        let calendar = CalendarView()
        calendar.dataSource = self
        view.addSubview(calendar)
```

The wiring is two lines of intent: assign a data source and later reload the data. User interaction is handled separately through `CalendarDelegate`, which you assign with a single line.

```swift
calendar.delegate = self
```

One thing to know before you copy the sample: it creates a variable named `calendar` and then calls `layoutIfNeeded()` on `calendarView` in the same class. That mismatch is in the published example, so expect to rename one of the two in your own code.

## Installation is a CocoaPods entry or a package URL

Two supported routes are documented. The CocoaPods route adds one entry to a Podfile.

```bash
pod 'KVKCalendar'
```

The Swift Package Manager route is described for Xcode 12 or higher: open File, then Swift Packages, then Add Package Dependency, select a project, paste the repository URL `https://github.com/kvyatkovskys/KVKCalendar`, and for Rules choose Version (Up to Next Major) before finishing. The version rule matters, because a library that offers five distinct view modules tends to add API surface in minor releases, and pinning to the next major keeps your build from drifting into a partially migrated state.

Platform requirements are listed as iOS 13.0+, iPadOS 13.0+ and macOS 11.0+ with Mac Catalyst support, and Swift 5.0+. The repository contains a `Package.swift`, a `KVKCalendar.podspec`, an `Example` directory with its own Xcode project and Podfile, and a `Tests` directory, so both build systems are exercised in the source tree. A `.swiftlint.yml` file at the root indicates the project lints itself with SwiftLint.

## Custom event views and custom cells are the extension points

Customisation is where this library puts its effort, and the mechanism is subclassing rather than configuration objects. To replace the view for one event you create a class inheriting from `EventViewGeneral` and return it from an optional data source method.

```swift
class CustomViewEvent: EventViewGeneral {
    override init(style: Style, event: Event, frame: CGRect) {
        super.init(style: style, event: event, frame: frame)
    }
}
```

Cell replacement follows the same pattern through an optional `dequeueCell` method that takes a `CellParameter`, a `CalendarType`, the backing scroll view and an `IndexPath`, then switches on the calendar type so the day, week and month case can reuse one cell class while year and list use their own.

The checklist in the documentation also names a custom header view and collection view, and a custom calendar localization. If your design system needs a bespoke look on every surface, this library gives you the hooks. If you only want a differently tinted event, the amount of subclassing required is more ceremony than a plain calendar view would ask of you.

## The feature checklist has one item left unchecked

The README carries a checklist of additional features, and one line is not ticked: skeleton loading for the month and list views. Everything else on the list is marked as done, including switching between time zones, dark mode, custom event views, custom date cells, custom header and collection views, custom calendar localization, the weekly event list mode, a configurable divider line for day and week views, multiple Windows on iPad, and UIMenu support in the event view.

That UIMenu entry carries a platform floor of iOS and Mac Catalyst 14.0+, which is higher than the stated iOS 13.0+ deployment target. In practice that means the menu based event actions only appear on newer systems, and the surrounding code has to handle their absence.

Switching between time zones is the other feature worth understanding before you build scheduling logic on top, because a calendar that re-renders in a different zone has to keep the underlying event instants fixed. The library provides the switch; how you source the zone list is your problem, since no provider is documented.

For troubleshooting, the documentation points questions to the StackOverflow tag for the project and reserves issues for bugs and feature requests.

## A release gap sits between the latest tag and the last commit

The repository is not archived and the last push was on 2026-09-03. The tagged releases tell a slower story: version 0.6.30 was published on 2025-11-02, version 0.6.29 on 2024-11-12 and version 0.6.28 on 2024-10-24. So there were three tagged versions inside two months in late 2024, a gap of about a year before 0.6.30, and roughly ten months of commits after it without a new tag.

Read together, that is a project in maintenance mode with occasional work rather than a monthly release train. The version numbering is still three-part, so you would not expect large breaking changes, but you also should not assume a new release lands when you need one. Locking to the exact version you tested is the safer choice with this cadence.

The licence is MIT and the repository carries a `LICENSE.md` file. That is the most permissive of the common open source licences and covers commercial use, modification and redistribution, including inside a closed source app, though it does require the licence text and copyright notice to be kept. This is a licensing observation about the terms themselves, not legal advice, and you should have your own counsel confirm the fit for your distribution model.

## Reading device calendars means going through EventKit yourself

The library shows events you give it, so where the events come from is entirely your decision. The sample data source implements a method that receives system events as `[EKEvent]`, maps each one with `Event(event:)`, and appends them to the events the app already had.

```swift
extension KVKCalendarVC: CalendarDataSource {
    func eventsForCalendar(systemEvents: [EKEvent]) -> [Event] {
        let mappedEvents = systemEvents.compactMap { Event(event: $0) }
        return events + mappedEvents
    }
}
```

That method is the seam between the two approaches. An app that wants Apple's own calendar database can query EventKit for `EKEvent` objects, hand them to the library, and get KVKCalendar's rendering on top. An app with its own backend can skip that entirely and build `Event` values from an API, as the first sample does.

This is also where the library differs from the platform alternative. Using EventKit and a plain date picker view means less code and no custom cell classes, but it also means giving up control over headers, event views and the monthly grid layout. KVKCalendar earns its place when the visual result has to match a design system, and it is the wrong tool when the calendar is a minor field in a larger form.

The SwiftUI path exists too. The documentation starts with creating a struct named `KVKCalendarWrapper`, and the example directory includes a SwiftUI info plist, so a SwiftUI integration is part of the project, though the wrapper section is cut short in the published instructions.

## Conclusion

Adopt KVKCalendar when your app needs a calendar whose cells, headers and event views it fully controls, and skip it when you want a drop in calendar backed by real device data, since the library renders what you hand it and does not persist events. Verify first that the deployment targets match your app, iOS 13.0+, iPadOS 13.0+, macOS 11.0+ with Swift 5.0+, and that the CocoaPods or Swift Package Manager route you choose matches how your project pins dependencies.

## FAQ

### How do I add KVKCalendar to my iOS project?

The documentation gives two routes: a CocoaPods entry `pod 'KVKCalendar'` in your Podfile, or adding the package in Xcode 12 or higher through File, Swift Packages, Add Package Dependency, using the repository URL `https://github.com/kvyatkovskys/KVKCalendar` and the Version (Up to Next Major) rule.

### What are the platform and Swift version requirements for KVKCalendar?

The stated requirements are iOS 13.0+, iPadOS 13.0+ and macOS 11.0+ with Mac Catalyst support, and Swift 5.0+. One feature, UIMenu support in the event view, is limited to iOS and Mac Catalyst 14.0+.

### How do I feed my own events into the calendar?

You build an array of `Event` values and return it from the `CalendarDataSource` protocol, then call reload on the calendar view. Events can also come from the device by mapping `[EKEvent]` objects in the data source method.

### Can I change how a day cell or an event looks?

Yes. You subclass `EventViewGeneral` and return your view from the optional `willDisplayEventView` method, and you replace cells through the optional `dequeueCell` method that switches on the calendar type for day, week, month, year and list views.

### Is KVKCalendar still being updated?

The repository is not archived and the last push was on 2026-09-03, but the most recent tagged release is 0.6.30 from 2025-11-02, with earlier tags 0.6.29 and 0.6.28 dating from November and October 2024. The pattern is intermittent maintenance rather than a steady release cadence.

## Sources

- [kvyatkovskys/KVKCalendar on GitHub](https://github.com/kvyatkovskys/KVKCalendar)
- [License: MIT](https://github.com/kvyatkovskys/KVKCalendar/blob/master/LICENSE)
- [Project website](https://kvyatkovskys.github.io/KVKCalendar/)
- [README](https://github.com/kvyatkovskys/KVKCalendar/blob/master/README.md)
- [Releases](https://github.com/kvyatkovskys/KVKCalendar/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/kvyatkovskys-kvkcalendar
