Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Anton Vodolazkyi committed Mar 4, 2018
0 parents commit 230c86b
Show file tree
Hide file tree
Showing 17 changed files with 1,681 additions and 0 deletions.
18 changes: 18 additions & 0 deletions VACalendar.podspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Pod::Spec.new do |s|
s.name = 'VACalendar'
s.version = '0.1.0'
s.summary = 'Custom Calendar for iOS in Swift'
s.swift_version = '4.0'

s.description = <<-DESC
VACalendar helps create customizable calendar for your app. It also supports vertical and horizontal scroll directions!
DESC

s.homepage = 'https://github.com/Vodolazkyi/VACalendar'
s.license = 'MIT'
s.author = { 'Anton Vodolazkyi' => '[email protected]' }
s.platform = :ios, '10.0'
s.source = { :git => 'https://github.com/Vodolazkyi/VACalendar.git', :tag => s.version.to_s }
s.source_files = 'VACalendar/Sources/*.swift'

end
380 changes: 380 additions & 0 deletions VACalendar.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

24 changes: 24 additions & 0 deletions VACalendar/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
121 changes: 121 additions & 0 deletions VACalendar/Sources/VACalendar.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
//
// VACalendar.swift
// VACalendar
//
// Created by Anton Vodolazkyi on 20.02.18.
// Copyright © 2018 Vodolazkyi. All rights reserved.
//

import Foundation

protocol VACalendarDelegate: class {
func selectedDaysDidUpdate(_ days: [VADay])
}

public enum DaysAvailability {
case all
case some([Date])
}

public class VACalendar {

var months = [VAMonth]()
weak var delegate: VACalendarDelegate?

private let calendar: Calendar
private var daysAvailability: DaysAvailability = .all

private var selectedDays = [VADay]() {
didSet {
delegate?.selectedDaysDidUpdate(selectedDays)
}
}

public init(
startDate: Date? = nil,
endDate: Date? = nil,
selectedDate: Date? = Date(),
calendar: Calendar = Calendar.current) {
self.calendar = calendar

if let selectedDate = selectedDate {
let day = VADay(date: selectedDate, state: .selected, calendar: calendar)
selectedDays = [day]
}

let startDate = startDate ?? calendar.date(byAdding: .year, value: -1, to: Date())!
let endDate = endDate ?? calendar.date(byAdding: .year, value: 1, to: Date())!
months = generateMonths(from: startDate, endDate: endDate)
}

func selectDay(_ day: VADay) {
months.first(where: { $0.dateInThisMonth(day.date) })?.setDaySelectionState(day, state:.selected)
selectedDays = [day]
}

func selectDates(_ dates: [Date]) {
let days = months.flatMap { $0.days(for: dates) }
days.forEach { $0.setSelectionState(.selected) }
selectedDays = days
}

func setDaysAvailability(_ availability: DaysAvailability) {
daysAvailability = availability

switch availability {
case .all:
let days = months.flatMap { $0.allDays() }
days.forEach { $0.setState(.available) }

case .some(let dates):
let allDays = months.flatMap { $0.allDays() }
allDays.forEach { $0.setState(.unavailable) }
let availableDays = dates.flatMap { date in allDays.filter { $0.dateInDay(date) }}
availableDays.forEach { $0.setState(.available) }
}
}

func setDaySelectionState(_ day: VADay, state: VADayState) {
months.first(where: { $0.dateInThisMonth(day.date) })?.setDaySelectionState(day, state: state)

if let index = selectedDays.index(of: day) {
selectedDays.remove(at: index)
} else {
selectedDays.append(day)
}
}

func setSupplementaries(_ data: [(Date, [VADaySupplementary])]) {
let dates = data.map { $0.0 }
let days = months.flatMap { $0.days(for: dates) }

days.forEach { day in
guard let supplementaries = data.first(where: { day.dateInDay($0.0) })?.1 else { return }
day.set(supplementaries)
}
}

func deselectAll() {
selectedDays = []
months.forEach { $0.deselectAll() }
}

private func generateMonths(from startDate: Date, endDate: Date) -> [VAMonth] {
let startComponents = calendar.dateComponents([.year, .month], from: startDate)
let endComponents = calendar.dateComponents([.year, .month], from: endDate)
var startDate = calendar.date(from: startComponents)!
let endDate = calendar.date(from: endComponents)!
var months = [VAMonth]()

repeat {
let date = startDate
let month = VAMonth(month: date, calendar: calendar)
month.selectedDays = selectedDays.filter { calendar.isDate($0.date, equalTo: startDate, toGranularity: .month) }
months.append(month)
startDate = calendar.date(byAdding: .month, value: 1, to: date)!
} while !calendar.isDate(startDate, inSameDayAs: endDate)

return months
}

}
5 changes: 5 additions & 0 deletions VACalendar/Sources/VACalendarMonthDelegate.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Foundation

public protocol VACalendarMonthDelegate: class {
func monthDidChange(_ currentMonth: Date)
}
Loading

0 comments on commit 230c86b

Please sign in to comment.