Skip to content

SwiftUI package to display iOS Calendar.app like timelines with event previews (GitHub mirror of canonical Codeberg repo)

License

Notifications You must be signed in to change notification settings

CleanCocoa/timeline-ui

Repository files navigation

TimelineUI

Codeberg Swift 6.2 iOS 26+

A SwiftUI component library for displaying calendar timeline views in iOS apps. Show daily schedules on an hour grid with automatic layout for overlapping events.

Installation

Add TimelineUI to your project using Swift Package Manager:

dependencies: [
    .package(url: "https://codeberg.org/ctietze/timeline-ui.git", from: "1.0.0")
]

Note: This project is canonically hosted on Codeberg. GitHub is a mirror.

Quick Start

import TimelineUI

struct ScheduleView: View {
    let events: [TimelineItem] = [
        TimelineItem(
            title: "Team Meeting",
            startDate: Date(),
            endDate: Date().addingTimeInterval(3600),
            color: .blue,
            location: "Conference Room A"
        ),
        TimelineItem(
            title: "Lunch",
            startDate: Date().addingTimeInterval(7200),
            endDate: Date().addingTimeInterval(10800),
            color: .green
        )
    ]

    var body: some View {
        DayTimelineView(items: events)
    }
}

Components

DayTimelineView

Full day timeline that automatically expands to fill available space. Shows hour grid lines with events positioned by time.

DayTimelineView(items: [TimelineItem])

CompactTimelineView

Compact timeline window, ideal for widgets or previews.

CompactTimelineView(items: [TimelineItem])                      // Fills available height
CompactTimelineView(items: [TimelineItem], heightMode: .flexible)      // Same as above
CompactTimelineView(items: [TimelineItem], heightMode: .fixed(hours: 2)) // Fixed 2-hour window

Expandable Timeline

Tap a compact timeline to expand into a full day view with a smooth matched geometry animation:

Expandable timeline animation

@State private var isExpanded = false
@Namespace private var timelineNamespace

// Compact view with tap-to-expand
CompactTimelineView(items: items, heightMode: .fixed(hours: 2))
    .timelineTransition(in: timelineNamespace)
    .onTapGesture {
        withAnimation(.spring(duration: 0.4, bounce: 0.15)) {
            isExpanded = true
        }
    }

// Apply expanded overlay at root level
.overlay {
    if isExpanded {
        ExpandedTimelineContent(items: items) { headerView }
            .timelineTransition(in: timelineNamespace)
    }
}

Access Restricted View

Show a blurred timeline with a permission prompt when calendar access hasn't been granted:

CompactTimelineView(items: [])
    .accessRestricted(!hasCalendarAccess) {
        AccessPromptView.calendar(style: .compact) {
            await requestCalendarAccess()
        }
    }

Customize the prompt text:

AccessPromptView.calendar(
    title: "Check for conflicts",
    message: "See if this time works with your schedule",
    buttonLabel: "Enable Calendar"
) { await requestAccess() }

Or use ViewBuilders for full control over icon and button:

AccessPromptView(
    title: "Connect Calendar",
    message: "Show your events on the timeline",
    icon: { Image(systemName: "calendar.badge.plus") },
    buttonLabel: { Label("Allow Access", systemImage: "checkmark.circle") }
) { await requestAccess() }

Screenshots

Light Dark
Compact - Focused 2-3 hour window Compact light Compact dark
Day - Full schedule with hour grid Day light Day dark
Overlapping - Events arranged side-by-side Overlapping light Overlapping dark
Many events - Handles busy schedules gracefully Many light Many dark
Access restricted - Blurred with permission prompt Restricted light Restricted dark

Requirements

  • iOS 26+
  • Swift 6.2+

License

MIT

About

SwiftUI package to display iOS Calendar.app like timelines with event previews (GitHub mirror of canonical Codeberg repo)

Topics

Resources

License

Stars

Watchers

Forks

Contributors 2

  •  
  •