From 2ea5926f4a4dcafddc4e8faf65470298e9a27ef6 Mon Sep 17 00:00:00 2001 From: Rakuyo Date: Fri, 30 Aug 2024 11:50:51 +0800 Subject: [PATCH 1/3] Allows more flexibility in setting year ranges --- Sources/KVKCalendar/CalendarData.swift | 31 ++++++++++++++++++++--- Sources/KVKCalendar/KVKCalendarView.swift | 31 ++++++++++++++++------- 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/Sources/KVKCalendar/CalendarData.swift b/Sources/KVKCalendar/CalendarData.swift index 71953e5e..119f656e 100644 --- a/Sources/KVKCalendar/CalendarData.swift +++ b/Sources/KVKCalendar/CalendarData.swift @@ -19,14 +19,37 @@ struct CalendarData { var yearsCount = [Int]() init(date: Date, years: Int, style: Style) { - self.date = date - self.style = style - // count years for calendar let indexesYear = [Int](repeating: 0, count: years).split(half: years / 2) + + self.init(date: date, style: style, indexesYear: indexesYear) + } + + init(date: Date, style: Style, startYear: Int, endYear: Int) { + let currentYear = Date().kvkYear + + // 2024 - 2024 -> (left: 0, right: 0) + // 2024 - 2026 -> (left: 0, right: 2) + // 2023 - 2026 -> (left: 1, right: 2) + // 2022 - 2026 -> (left: 2, right: 2) + let leftCount = currentYear - min(startYear, currentYear) + let rightCount = max(endYear, currentYear) - currentYear + + let left = [Int](repeating: 0, count: leftCount) + let right = [Int](repeating: 0, count: rightCount) + + self.init(date: date, style: style, indexesYear: (left, right)) + } + + private init(date: Date, style: Style, indexesYear: (left: [Int], right: [Int])) { + self.date = date + self.style = style + let lastYear = indexesYear.left let nextYear = indexesYear.right - + + let years = lastYear.count + nextYear.count + // last years for lastIdx in lastYear.indices.reversed() where years > 1 { yearsCount.append(-lastIdx) diff --git a/Sources/KVKCalendar/KVKCalendarView.swift b/Sources/KVKCalendar/KVKCalendarView.swift index f30c5dfc..0a8b7b0c 100644 --- a/Sources/KVKCalendar/KVKCalendarView.swift +++ b/Sources/KVKCalendar/KVKCalendarView.swift @@ -48,10 +48,20 @@ public final class KVKCalendarView: UIView { private(set) var yearView: YearView private(set) var listView: ListView - public init(frame: CGRect, date: Date? = nil, style: Style = Style(), years: Int = 4) { + public convenience init(frame: CGRect, date: Date? = nil, style: Style = Style(), years: Int = 4) { + let calendarData = CalendarData(date: date ?? Date(), years: years, style: style.adaptiveStyle) + self.init(frame: frame, date: date, style: style, calendarData: calendarData) + } + + public convenience init(frame: CGRect, date: Date? = nil, style: Style = Style(), startYear: Int, endYear: Int) { + let calendarData = CalendarData(date: date ?? Date(), style: style.adaptiveStyle, startYear: startYear, endYear: endYear) + self.init(frame: frame, date: date, style: style, calendarData: calendarData) + } + + private init(frame: CGRect, date: Date?, style: Style, calendarData: CalendarData) { let adaptiveStyle = style.adaptiveStyle self.parameters = .init(type: style.defaultType ?? .day, style: adaptiveStyle) - self.calendarData = CalendarData(date: date ?? Date(), years: years, style: adaptiveStyle) + self.calendarData = calendarData // day view self.dayData = DayData(data: calendarData, startDay: adaptiveStyle.startWeekDay) @@ -81,6 +91,14 @@ public final class KVKCalendarView: UIView { super.init(frame: frame) + setup(with: date) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setup(with date: Date?) { dayView.scrollableWeekView.dataSource = self dayView.dataSource = self dayView.delegate = self @@ -103,17 +121,12 @@ public final class KVKCalendarView: UIView { viewCaches = [.day: dayView, .week: weekView, .month: monthView, .year: yearView, .list: listView] - if let defaultType = adaptiveStyle.defaultType { + if let defaultType = style.adaptiveStyle.defaultType { parameters.type = defaultType } set(type: parameters.type, date: date) - reloadAllStyles(adaptiveStyle, force: true) + reloadAllStyles(style.adaptiveStyle, force: true) } - - required init?(coder aDecoder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - } #endif From 5b046d832baa5c2659f463a2760c342b34417a91 Mon Sep 17 00:00:00 2001 From: Rakuyo Date: Fri, 6 Sep 2024 11:33:44 +0800 Subject: [PATCH 2/3] Fix the problem of incorrect calculation of start time --- Sources/KVKCalendar/CalendarData.swift | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Sources/KVKCalendar/CalendarData.swift b/Sources/KVKCalendar/CalendarData.swift index 119f656e..8fba1eec 100644 --- a/Sources/KVKCalendar/CalendarData.swift +++ b/Sources/KVKCalendar/CalendarData.swift @@ -28,11 +28,13 @@ struct CalendarData { init(date: Date, style: Style, startYear: Int, endYear: Int) { let currentYear = Date().kvkYear - // 2024 - 2024 -> (left: 0, right: 0) - // 2024 - 2026 -> (left: 0, right: 2) - // 2023 - 2026 -> (left: 1, right: 2) - // 2022 - 2026 -> (left: 2, right: 2) - let leftCount = currentYear - min(startYear, currentYear) + // 2024 - 2024 -> (left: 1, right: 0) + // 2024 - 2026 -> (left: 1, right: 2) + // 2023 - 2026 -> (left: 2, right: 2) + // 2022 - 2026 -> (left: 3, right: 2) + + // +1 means adding the current year to the data + let leftCount = currentYear - min(startYear, currentYear) + 1 let rightCount = max(endYear, currentYear) - currentYear let left = [Int](repeating: 0, count: leftCount) From 4030d523b7c8226ed6baff06bc90f12c02086921 Mon Sep 17 00:00:00 2001 From: Rakuyo Date: Mon, 9 Sep 2024 12:16:07 +0800 Subject: [PATCH 3/3] Adding the Range parameter --- Example/Pods/Pods.xcodeproj/project.pbxproj | 4 ++++ Sources/KVKCalendar/CalendarData.swift | 4 ++++ Sources/KVKCalendar/KVKCalendarView.swift | 4 ++++ Sources/KVKCalendar/YearRange.swift | 22 +++++++++++++++++++++ 4 files changed, 34 insertions(+) create mode 100644 Sources/KVKCalendar/YearRange.swift diff --git a/Example/Pods/Pods.xcodeproj/project.pbxproj b/Example/Pods/Pods.xcodeproj/project.pbxproj index 970320ff..8bf9ee29 100644 --- a/Example/Pods/Pods.xcodeproj/project.pbxproj +++ b/Example/Pods/Pods.xcodeproj/project.pbxproj @@ -48,6 +48,7 @@ A6389BA2A93A24D40BB15DDD11991ADE /* DayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F68932F57BDD715B5D6BEEF06CC1FCD6 /* DayView.swift */; }; AB96EF6BCB31ECE9776304B14095F45F /* VerticalLineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5B9F168F53433DE04559DB38434F9A3 /* VerticalLineView.swift */; }; AC5EC59350B748CF19754D772408407E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B907F9B2E7D0EE7E7174FFA2429E0E9 /* Foundation.framework */; }; + AE882EE62C8EAA2600905875 /* YearRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE882EE52C8EAA2600905875 /* YearRange.swift */; }; B45BCEFC6AFF9BE9BEE5CC6408B4919B /* Pods-KVKCalendar_Example-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A76D757EA13402410F2D5EE506F35E2 /* Pods-KVKCalendar_Example-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; B9DBC73772DE7129AC943058E32A2D23 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B907F9B2E7D0EE7E7174FFA2429E0E9 /* Foundation.framework */; }; BAA9431D27091AB5ECD2706A2953F615 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 19A3231A79E41DA09914180F11687F82 /* UIKit.framework */; }; @@ -148,6 +149,7 @@ AB364C8715A22990F1D7C8B6FDE7F94F /* EventKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = EventKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/EventKit.framework; sourceTree = DEVELOPER_DIR; }; AD144A2432F96A11EBF7681230A39D4F /* DayPhoneCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DayPhoneCell.swift; path = Sources/KVKCalendar/DayPhoneCell.swift; sourceTree = ""; }; AD583DD1362817FC0C076C2BD05EFFEF /* YearHeaderView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = YearHeaderView.swift; path = Sources/KVKCalendar/YearHeaderView.swift; sourceTree = ""; }; + AE882EE52C8EAA2600905875 /* YearRange.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = YearRange.swift; path = Sources/KVKCalendar/YearRange.swift; sourceTree = ""; }; B680BCD917ECF76AB806C6A47376868B /* ListViewHeader.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ListViewHeader.swift; path = Sources/KVKCalendar/ListViewHeader.swift; sourceTree = ""; }; C3178112F6DC9E787B37268E14F9F5F8 /* KVKCalendar-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "KVKCalendar-Info.plist"; sourceTree = ""; }; C3ABA57A741ED998EDFDB563FD27D8EA /* DayData.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DayData.swift; path = Sources/KVKCalendar/DayData.swift; sourceTree = ""; }; @@ -350,6 +352,7 @@ F9535B32272DE8CC008AAC56 /* KVKTableViewCell.swift */, F9535B34272DE9F5008AAC56 /* KVKTableViewHeaderFooterView.swift */, F98F027E2924C38500416B9A /* SwiftUI+Extensions.swift */, + AE882EE52C8EAA2600905875 /* YearRange.swift */, ); name = KVKCalendar; path = ../..; @@ -582,6 +585,7 @@ 1854C4D2AAD2F8BFB7D5D885FC47C049 /* Timeline+Extension.swift in Sources */, 3FE8D0253ABE9B61C42F2322700FAFA0 /* TimelineContainerVC.swift in Sources */, 50DA4CC293A9226D0714437AACC4D56E /* TimelineLabel.swift in Sources */, + AE882EE62C8EAA2600905875 /* YearRange.swift in Sources */, E1C90EFE7122604D8AF4C22238583017 /* TimelineModel.swift in Sources */, 9BEF9E81BF5DC17136FD762AC5A2BADA /* TimelinePageView.swift in Sources */, 17B97139898B1CE05B2505DBC30FFC65 /* TimelineView.swift in Sources */, diff --git a/Sources/KVKCalendar/CalendarData.swift b/Sources/KVKCalendar/CalendarData.swift index 8fba1eec..ec16c9b5 100644 --- a/Sources/KVKCalendar/CalendarData.swift +++ b/Sources/KVKCalendar/CalendarData.swift @@ -25,6 +25,10 @@ struct CalendarData { self.init(date: date, style: style, indexesYear: indexesYear) } + init(date: Date, style: Style, yearRange: R) where R.Bound == Int { + self.init(date: date, style: style, startYear: yearRange.lowerBound, endYear: yearRange.upperBound) + } + init(date: Date, style: Style, startYear: Int, endYear: Int) { let currentYear = Date().kvkYear diff --git a/Sources/KVKCalendar/KVKCalendarView.swift b/Sources/KVKCalendar/KVKCalendarView.swift index 0a8b7b0c..9ac1cdd2 100644 --- a/Sources/KVKCalendar/KVKCalendarView.swift +++ b/Sources/KVKCalendar/KVKCalendarView.swift @@ -53,6 +53,10 @@ public final class KVKCalendarView: UIView { self.init(frame: frame, date: date, style: style, calendarData: calendarData) } + public convenience init(frame: CGRect, date: Date? = nil, style: Style = Style(), yearRange: R) where R.Bound == Int { + self.init(frame: frame, date: date, style: style, startYear: yearRange.lowerBound, endYear: yearRange.upperBound) + } + public convenience init(frame: CGRect, date: Date? = nil, style: Style = Style(), startYear: Int, endYear: Int) { let calendarData = CalendarData(date: date ?? Date(), style: style.adaptiveStyle, startYear: startYear, endYear: endYear) self.init(frame: frame, date: date, style: style, calendarData: calendarData) diff --git a/Sources/KVKCalendar/YearRange.swift b/Sources/KVKCalendar/YearRange.swift new file mode 100644 index 00000000..e08637b4 --- /dev/null +++ b/Sources/KVKCalendar/YearRange.swift @@ -0,0 +1,22 @@ +// +// YearRange.swift +// KVKCalendar +// +// Created by Rakuyo on 9.9.2024. +// + +import Foundation + +public protocol YearRange { + associatedtype Bound: Comparable + + /// The range's lower bound. + var lowerBound: Bound { get } + + /// The range's upper bound. + var upperBound: Bound { get } +} + +extension Range: YearRange { } + +extension ClosedRange: YearRange { }