Swiftpack.co -  kvyatkovskys/KVKCalendar as Swift Package
Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
A most fully customization calendar and timeline library for iOS 📅
.package(url: "https://github.com/kvyatkovskys/KVKCalendar.git", from: "0.4.9")

CI Status Version Carthage SwiftPM compatible Platform License


KVKCalendar is a most fully customization calendar and timeline library. Library consists of four modules for displaying various types of calendar (day, week, month, year). You can choose any module or use all. It is designed based on a standard iOS calendar, but with additional features. Timeline displays the schedule for the day and week.

Need Help?

If you have a question about how to use KVKCalendar in your application, ask it on StackOverflow using the KVKCalendar tag.

Please, use Issues only for reporting bugs or requesting a new features in the library.


  • iOS 10.0+, iPadOS 10.0+, MacOS 10.15+ (Supports Mac Catalyst)
  • Swift 5.0+


KVKCalendar is available through CocoaPods or Carthage or Swift Package Manager.


pod 'KVKCalendar'

Adding Pods to an Xcode project


github "kvyatkovskys/KVKCalendar"

Adding Frameworks to an Xcode project

Swift Package Manager (Xcode 12 or higher)

  1. In Xcode navigate to FileSwift PackagesAdd Package Dependency...
  2. Select a project
  3. Paste the repository URL (https://github.com/kvyatkovskys/KVKCalendar.git) and click Next.
  4. For Rules, select Version (Up to Next Major) and click Next.
  5. Click Finish.

Adding Package Dependencies to Your App

Usage for UIKit

Import KVKCalendar. Create a subclass view CalendarView and implement CalendarDataSource protocol. Create an array of class [Event] and return the array.

import KVKCalendar

class ViewController: UIViewController {
    var events = [Event](https://raw.github.com/kvyatkovskys/KVKCalendar/master/)

    override func viewDidLoad() {
        let calendar = CalendarView(frame: frame)
        calendar.dataSource = self
        createEvents { (events) in
            self.events = events
    override func viewDidLayoutSubviews() {

extension ViewController {
    func createEvents(completion: ([Event]) -> Void) {
        let models = // Get events from storage / API
        let events = models.compactMap({ (item) in
            var event = Event(ID: item.id)
            event.start = item.startDate // start date event
            event.end = item.endDate // end date event
            event.color = item.color
            event.isAllDay = item.allDay
            event.isContainsFile = !item.files.isEmpty
            event.recurringType = // recurring event type - .everyDay, .everyWeek
            // Add text event (title, info, location, time)
            if item.allDay {
                event.text = "\(item.title)"
            } else {
                event.text = "\(startTime) - \(endTime)\n\(item.title)"
            return event

extension ViewController: CalendarDataSource {
    func eventsForCalendar(systemEvents: [EKEvent]) -> [Event] {
        // if you want to get events from iOS calendars
        // set calendar names to style.systemCalendars = ["Test"]
        let mappedEvents = systemEvents.compactMap({ $0.transform() })
        return events + mappedEvents

Implement CalendarDelegate to handle user action and control calendar behaviour.

calendar.delegate = self

To use a custom view for specific event or date you need to create a new view of class EventViewGeneral and return the view in function.

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

// an optional function from CalendarDataSource
func willDisplayEventView(_ event: Event, frame: CGRect, date: Date?) -> EventViewGeneral? {
    guard event.ID == id else<img style="max-width:100%;" src="https://raw.github.com/kvyatkovskys/KVKCalendar/master/nil }
    return customEventView

To use a custom date cell, just subscribe on this optional method from CalendarDataSource (works for Day/Week/Month/Year views).

func dequeueCell<T>(date: Date?, type: CalendarType, view: T, indexPath: IndexPath) -> KVKCalendarCellProtocol? where T: UIScrollView { 
    switch type {
    case .year:
        let cell = (view as? UICollectionView)?.dequeueCell(indexPath: indexPath) { (cell: CustomYearCell) in
            // configure the cell
        return cell
    case .day, .week, .month:    
        let cell = (view as? UICollectionView)?.dequeueCell(indexPath: indexPath) { (cell: CustomDayCell) in
            // configure the cell
        return cell
    case .list:    
        let cell = (view as? UITableView)?.dequeueCell { (cell: CustomListCell) in
            // configu<img style="max-width:100%;" src="https://raw.github.com/kvyatkovskys/KVKCalendar/master/l
        return cell

Usage for SwiftUI

Add a new SwiftUI file and import KVKCalendar. Create a struct CalendarDisplayView and declare the protocol UIViewRepresentable for connection UIKit with SwiftUI.

import SwiftUI
import KVKCalendar

struct CalendarDisplayView: UIViewRepresentable {
    @Binding var events: [Event]

    private var calendar: CalendarView = {
        return CalendarView(frame: frame, style: style)
    func makeUIView(context: UIViewRepresentableContext<CalendarDisplayView>) -> CalendarView {
        calendar.dataSource = context.coordinator
        calendar.delegate = context.coordinator
        return calendar
    func updateUIView(_ uiView: CalendarView, context: UIViewRepresentableContext<CalendarDisplayView>) {
        context.coordinator.events = events
    func makeCoordinator() -> CalendarDisplayView.Coordinator {
    public init(events: Binding<[Event]>) {
        self._events = events
    // MARK: Calendar DataSource and Delegate
    class Coordinator: NSObject, CalendarDataSource, CalendarDelegate {
        private let view: CalendarDisplayView
        var events: [Event] = [] {
            didSet {
        init(_ view: CalendarDisplayView) {
            self.view = view
        func eventsForCalendar(systemEvents: [EKEvent]) -> [Event] {
            return events

Create a new SwiftUI file and add CalendarDisplayView to body.

import SwiftUI

struct CalendarContentView: View {
    @State var events: [Event] = []

    var body: some View {
        NavigationView {
            CalendarDisplayView(events: $events)


To customize calendar create an object Style and add to init class CalendarView.

public struct Style {
    public var event = EventStyle()
    public var timeline = TimelineStyle()
    public var week = WeekStyle()
    public var allDay = AllDayStyle()
    public var headerScroll = HeaderScrollStyle()
    public var month = MonthStyle()
    public var year = YearStyle()
    public var list = ListViewStyle()
    public var locale = Locale.current
    public var calendar = Calendar.current
    public var timezone = TimeZone.current
    public var defaultType: CalendarType?
    public var timeHourSystem: TimeHourSystem = .twentyFourHour
    public var startWeekDay: StartDayType = .monday
    public var followInSystemTheme: Bool = false 
    public var systemCalendars: Set<String> = []


Sergei Kviatkovskii


KVKCalendar is available under the MIT license


Stars: 178
Last commit: 1 hour ago

Ad: Job Offers

iOS Software Engineer @ Perry Street Software
Perry Street Software is Jack’d and SCRUFF. We are two of the world’s largest gay, bi, trans and queer social dating apps on iOS and Android. Our brands reach more than 20 million members worldwide so members can connect, meet and express themselves on a platform that prioritizes privacy and security. We invest heavily into SwiftUI and using Swift Packages to modularize the codebase.

Release Notes

Fixing release
1 year ago

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API