diff --git a/Example/KVKCalendar/events.json b/Example/KVKCalendar/events.json index 45d95f23..4911fa28 100644 --- a/Example/KVKCalendar/events.json +++ b/Example/KVKCalendar/events.json @@ -346,7 +346,7 @@ "id": "12", "border_color": "#FFFFFF", "color": "#ed6160", - "end": "2022-12-15T14:00:00+03:00", + "end": "2022-12-17T14:00:00+03:00", "start": "2022-12-14T13:30:00+03:00", "text_color": "#000000", "title": "Event number 16", diff --git a/KVKCalendar.podspec b/KVKCalendar.podspec index 5c8d1e55..73d491fa 100644 --- a/KVKCalendar.podspec +++ b/KVKCalendar.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'KVKCalendar' - s.version = '0.6.10' + s.version = '0.6.11' s.summary = 'A most fully customization calendar for Apple platforms.' s.description = <<-DESC diff --git a/Sources/KVKCalendar/Calendar+Extension.swift b/Sources/KVKCalendar/Calendar+Extension.swift index dfcb5682..14973b0d 100644 --- a/Sources/KVKCalendar/Calendar+Extension.swift +++ b/Sources/KVKCalendar/Calendar+Extension.swift @@ -99,6 +99,15 @@ extension UIScrollView { extension UIApplication { + var orientation: UIInterfaceOrientation { + if #available(iOS 13.0, *) { + return UIApplication.shared.windows.first?.windowScene?.interfaceOrientation ?? .unknown + } else { + let value = UIDevice.current.orientation + return UIInterfaceOrientation(rawValue: value.rawValue) ?? .unknown + } + } + var isAvailableBottomHomeIndicator: Bool { if #available(iOS 15.0, *) { if let keyWindow = UIApplication.shared.connectedScenes diff --git a/Sources/KVKCalendar/Date+Extension.swift b/Sources/KVKCalendar/Date+Extension.swift index 4677e586..2168ea7c 100644 --- a/Sources/KVKCalendar/Date+Extension.swift +++ b/Sources/KVKCalendar/Date+Extension.swift @@ -136,7 +136,7 @@ public extension Date { return Date(timeInterval: seconds, since: self) } - func convertTimeZone(_ initTimeZone: TimeZone, to timeZone: TimeZone) -> Date { + func kvkConvertTimeZone(_ initTimeZone: TimeZone, to timeZone: TimeZone) -> Date { let value = TimeInterval(timeZone.secondsFromGMT() - initTimeZone.secondsFromGMT()) var components = DateComponents() components.second = Int(value) @@ -144,12 +144,12 @@ public extension Date { return date ?? self } - func isSameDay(otherDate: Date) -> Bool { + func kvkIsSameDay(otherDate: Date) -> Bool { let diff = Calendar.current.dateComponents([.day], from: self, to: otherDate) return diff.day == 0 } - func addingTo(_ component: Calendar.Component, value: Int) -> Date? { + func kvkAddingTo(_ component: Calendar.Component, value: Int) -> Date? { if let newDate = Calendar.current.date(byAdding: component, value: value, to: self) { return newDate } @@ -157,7 +157,11 @@ public extension Date { return nil } - func isEqual(_ date: Date) -> Bool { + func kvkIsEqual(_ date: Date) -> Bool { date.kvkYear == kvkYear && date.kvkMonth == kvkMonth && date.kvkDay == kvkDay } + + var kvkIsFebruary: Bool { + kvkMonth == 2 + } } diff --git a/Sources/KVKCalendar/DayCell.swift b/Sources/KVKCalendar/DayCell.swift index b5ca270a..27a799ef 100644 --- a/Sources/KVKCalendar/DayCell.swift +++ b/Sources/KVKCalendar/DayCell.swift @@ -141,7 +141,7 @@ class DayCell: UICollectionViewCell { private func populateDay(date: Date?, colorText: UIColor) { let nowDate = Date() - if date?.isEqual(nowDate) == true { + if date?.kvkIsEqual(nowDate) == true { dateLabel.textColor = UIScreen.isDarkMode ? style.headerScroll.colorCurrentSelectDateForDarkStyle : style.headerScroll.colorCurrentDate dotView.backgroundColor = style.headerScroll.colorBackgroundCurrentDate } else { diff --git a/Sources/KVKCalendar/DayView.swift b/Sources/KVKCalendar/DayView.swift index ef5f104a..d16cf063 100644 --- a/Sources/KVKCalendar/DayView.swift +++ b/Sources/KVKCalendar/DayView.swift @@ -78,7 +78,7 @@ final class DayView: UIView { @discardableResult private func updateEventViewer(frame: CGRect) -> CGRect? { var viewerFrame = frame // hard reset the width when we change the orientation - if UIDevice.current.orientation.isPortrait { + if UIApplication.shared.orientation.isPortrait { viewerFrame.size.width = bounds.width * 0.5 viewerFrame.origin.x = viewerFrame.width } else { @@ -324,7 +324,7 @@ extension DayView: CalendarSettingProtocol { } if isAvailableEventViewer { - if UIDevice.current.orientation.isPortrait { + if UIApplication.shared.orientation.isPortrait { timelineFrame.size.width = UIScreen.main.bounds.width * 0.5 } else { timelineFrame.size.width -= style.timeline.widthEventViewer ?? 0 diff --git a/Sources/KVKCalendar/ListView.swift b/Sources/KVKCalendar/ListView.swift index 6ab987b3..18958481 100644 --- a/Sources/KVKCalendar/ListView.swift +++ b/Sources/KVKCalendar/ListView.swift @@ -100,7 +100,7 @@ public final class ListView: UIView, CalendarSettingProtocol { guard !params.data.isSkeletonVisible else { return } - if let idx = params.data.sections.firstIndex(where: { $0.date.isEqual(date) }) { + if let idx = params.data.sections.firstIndex(where: { $0.date.kvkIsEqual(date) }) { tableView.scrollToRow(at: IndexPath(row: 0, section: idx), at: .top, animated: animated) } else if let idx = params.data.sections.firstIndex(where: { $0.date.kvkYear == date.kvkYear && $0.date.kvkMonth == date.kvkMonth }) { tableView.scrollToRow(at: IndexPath(row: 0, section: idx), at: .top, animated: animated) diff --git a/Sources/KVKCalendar/ListViewData.swift b/Sources/KVKCalendar/ListViewData.swift index f0158f3a..92296a7f 100644 --- a/Sources/KVKCalendar/ListViewData.swift +++ b/Sources/KVKCalendar/ListViewData.swift @@ -55,7 +55,7 @@ public final class ListViewData: EventDateProtocol { if let date = lastDate, let calendar = style?.calendar { let recurringSections = addRecurringEvent(event, lastDate: date, calendar: calendar) recurringSections.forEach { (recurringSection) in - if let idx = accTemp.firstIndex(where: { $0.date.isEqual(recurringSection.date) }) { + if let idx = accTemp.firstIndex(where: { $0.date.kvkIsEqual(recurringSection.date) }) { accTemp[idx].events += recurringSection.events accTemp[idx].events = accTemp[idx].events.sorted(by: { $0.start < $1.start }) } else { diff --git a/Sources/KVKCalendar/MonthCell.swift b/Sources/KVKCalendar/MonthCell.swift index 9d48c6d1..798f6a51 100644 --- a/Sources/KVKCalendar/MonthCell.swift +++ b/Sources/KVKCalendar/MonthCell.swift @@ -82,7 +82,7 @@ final class MonthCell: KVKCollectionViewCell { return } - if Platform.currentInterface == .phone && UIDevice.current.orientation.isLandscape { return } + if Platform.currentInterface == .phone && UIApplication.shared.orientation.isLandscape { return } if monthStyle.showMonthNameInFirstDay { showMonthName(day: day) @@ -360,7 +360,7 @@ final class MonthCell: KVKCollectionViewCell { guard day.type != .empty else { return } guard date?.kvkYear == nowDate.kvkYear else { - if date?.isEqual(selectDate) == true { + if date?.kvkIsEqual(selectDate) == true { label.textColor = monthStyle.colorSelectDate label.backgroundColor = monthStyle.colorBackgroundSelectDate label.layer.cornerRadius = label.frame.height / 2 diff --git a/Sources/KVKCalendar/MonthData.swift b/Sources/KVKCalendar/MonthData.swift index 09c9956a..ea4e3ed0 100644 --- a/Sources/KVKCalendar/MonthData.swift +++ b/Sources/KVKCalendar/MonthData.swift @@ -116,6 +116,23 @@ final class MonthData: EventDateProtocol { return selectedDates } + func findNextDateInMonth(_ month: Month) -> Date { + if let date = month.days.first(where: { $0.date?.kvkYear == month.date.kvkYear + && $0.date?.kvkMonth == month.date.kvkMonth + && $0.date?.kvkDay == date.kvkDay })?.date { + return date + } else if let date = month.days.first(where: { $0.date?.kvkYear == month.date.kvkYear + && $0.date?.kvkMonth == month.date.kvkMonth + && $0.date?.kvkDay == (date.kvkDay - 1) })?.date { + return date + } else if month.date.kvkIsFebruary { + // check for only February + return month.days.last(where: { $0.type != .empty })?.date ?? Date() + } else { + return Date() + } + } + func reloadEventsInDays(events: [Event], date: Date) -> (events: [Event], dates: [Date?]) { let recurringEvents = events.filter { $0.recurringType != .none } guard let idxSection = data.months.firstIndex(where: { $0.date.kvkMonth == date.kvkMonth && $0.date.kvkYear == date.kvkYear }) else { @@ -126,7 +143,7 @@ final class MonthData: EventDateProtocol { var displayableEvents = [Event]() let updatedDays = days.reduce([], { (acc, day) -> [Day] in var newDay = day - let filteredEventsByDay = events.filter { compareStartDate(day.date, with: $0) && !$0.isAllDay } + let filteredEventsByDay = events.filter { (compareStartDate(day.date, with: $0) || checkMultipleDate(day.date, with: $0, checkMonth: true)) && !$0.isAllDay } let filteredAllDayEvents = events.filter { $0.isAllDay } let allDayEvents = filteredAllDayEvents.filter { compareStartDate(day.date, with: $0) diff --git a/Sources/KVKCalendar/MonthView.swift b/Sources/KVKCalendar/MonthView.swift index c5f6dc0d..6c3a0a7d 100644 --- a/Sources/KVKCalendar/MonthView.swift +++ b/Sources/KVKCalendar/MonthView.swift @@ -413,12 +413,9 @@ extension MonthView: UICollectionViewDelegate, UICollectionViewDelegateFlowLayou guard let index = objectView.indexPathForItem(at: center) else { return } let month = parameters.monthData.data.months[index.section] - guard style.month.autoSelectionDateWhenScrolling, - let newDate = month.days.first(where: { $0.date?.kvkYear == month.date.kvkYear - && $0.date?.kvkMonth == month.date.kvkMonth - && $0.date?.kvkDay == parameters.monthData.date.kvkDay })?.date, - parameters.monthData.date != newDate - else { return } + guard style.month.autoSelectionDateWhenScrolling else { return } + let newDate = parameters.monthData.findNextDateInMonth(month) + guard parameters.monthData.date != newDate else { return } parameters.monthData.date = newDate willSelectDate?(newDate) @@ -441,20 +438,7 @@ extension MonthView: UICollectionViewDelegate, UICollectionViewDelegateFlowLayou let month = parameters.monthData.data.months[visibleIndex] weekHeaderView.date = month.date guard style.month.autoSelectionDateWhenScrolling else { return } - - let newDate: Date - if let date = month.days.first(where: { $0.date?.kvkYear == month.date.kvkYear - && $0.date?.kvkMonth == month.date.kvkMonth - && $0.date?.kvkDay == parameters.monthData.date.kvkDay })?.date { - newDate = date - } else if let date = month.days.first(where: { $0.date?.kvkYear == month.date.kvkYear - && $0.date?.kvkMonth == month.date.kvkMonth - && $0.date?.kvkDay == (parameters.monthData.date.kvkDay - 1) })?.date { - newDate = date - } else { - newDate = Date() - } - + let newDate = parameters.monthData.findNextDateInMonth(month) guard parameters.monthData.date != newDate else { return } parameters.monthData.date = newDate @@ -519,8 +503,7 @@ extension MonthView: UICollectionViewDelegate, UICollectionViewDelegateFlowLayou let month = parameters.monthData.data.months[indexPath.section] let index = IndexPath(row: 0, section: indexPath.section) - if let headerView = dataSource?.dequeueHeader(date: month.date, type: .month, view: collectionView, indexPath: index) as? UICollectionReusableView - { + if let headerView = dataSource?.dequeueHeader(date: month.date, type: .month, view: collectionView, indexPath: index) as? UICollectionReusableView { return headerView } else { return collectionView.kvkDequeueView(indexPath: index) { (headerView: MonthHeaderView) in diff --git a/Sources/KVKCalendar/ScrollableWeekView.swift b/Sources/KVKCalendar/ScrollableWeekView.swift index 7bca93c8..db57d64f 100644 --- a/Sources/KVKCalendar/ScrollableWeekView.swift +++ b/Sources/KVKCalendar/ScrollableWeekView.swift @@ -95,7 +95,7 @@ final class ScrollableWeekView: UIView { func getIdxByDate(_ date: Date) -> Int? { weeks.firstIndex(where: { week in - week.firstIndex(where: { $0.date?.isEqual(date) ?? false }) != nil + week.firstIndex(where: { $0.date?.kvkIsEqual(date) ?? false }) != nil }) } diff --git a/Sources/KVKCalendar/Style.swift b/Sources/KVKCalendar/Style.swift index 0e450cb1..0a5ba61a 100644 --- a/Sources/KVKCalendar/Style.swift +++ b/Sources/KVKCalendar/Style.swift @@ -263,9 +263,9 @@ public struct TimelineStyle { return true case .today: let date = Date() - return dates.contains(where: { date.isEqual($0) }) + return dates.contains(where: { date.kvkIsEqual($0) }) case .forDate(let date): - return dates.contains(where: { date.isEqual($0) }) + return dates.contains(where: { date.kvkIsEqual($0) }) case .never: return false } @@ -282,9 +282,9 @@ public struct TimelineStyle { return true case .today: let date = Date() - return dates.contains(where: { date.isEqual($0) }) + return dates.contains(where: { date.kvkIsEqual($0) }) case .forDate(let date), .onlyOnInitForDate(let date): - return dates.contains(where: { date.isEqual($0) }) + return dates.contains(where: { date.kvkIsEqual($0) }) case .never: return false } diff --git a/Sources/KVKCalendar/TimelineModel.swift b/Sources/KVKCalendar/TimelineModel.swift index 4752308d..73d61237 100644 --- a/Sources/KVKCalendar/TimelineModel.swift +++ b/Sources/KVKCalendar/TimelineModel.swift @@ -60,13 +60,13 @@ extension EventDateProtocol { func compareStartDate(_ date: Date?, with event: Event) -> Bool { guard let dt = date else { return false } - return event.start.isEqual(dt) + return event.start.kvkIsEqual(dt) } func compareEndDate(_ date: Date?, with event: Event) -> Bool { guard let dt = date else { return false } - return event.end.isEqual(dt) + return event.end.kvkIsEqual(dt) } func checkMultipleDate(_ date: Date?, with event: Event, checkMonth: Bool = false) -> Bool { diff --git a/Sources/KVKCalendar/TimelineView.swift b/Sources/KVKCalendar/TimelineView.swift index 49e8d4be..f76e66d7 100644 --- a/Sources/KVKCalendar/TimelineView.swift +++ b/Sources/KVKCalendar/TimelineView.swift @@ -145,7 +145,7 @@ final class TimelineView: UIView, EventDateProtocol, CalendarTimer { let action = { [weak self] in guard let self = self else { return } - let nextDate = Date().convertTimeZone(TimeZone.current, to: self.style.timezone) + let nextDate = Date().kvkConvertTimeZone(TimeZone.current, to: self.style.timezone) guard self.currentLineView.valueHash != nextDate.kvkMinute.hashValue, let time = self.getTimelineLabel(hour: nextDate.kvkHour) else { return } @@ -173,7 +173,7 @@ final class TimelineView: UIView, EventDateProtocol, CalendarTimer { private func showCurrentLineHour() { currentLineView.isHidden = !isDisplayedCurrentTime - let date = Date().convertTimeZone(TimeZone.current, to: style.timezone) + let date = Date().kvkConvertTimeZone(TimeZone.current, to: style.timezone) guard style.timeline.showLineHourMode.showForDates(dates), let time = getTimelineLabel(hour: date.kvkHour) else { stopTimer(timerKey) diff --git a/Sources/KVKCalendar/WeekData.swift b/Sources/KVKCalendar/WeekData.swift index 3526f2e5..56950cd8 100644 --- a/Sources/KVKCalendar/WeekData.swift +++ b/Sources/KVKCalendar/WeekData.swift @@ -51,13 +51,13 @@ final class WeekData: EventDateProtocol, ScrollableWeekProtocol { var extensionDays: [Day] = [] if maxDays != 7, - let indexOfInputDate = defaultDays.firstIndex(where: { $0.date?.isSameDay(otherDate: data.date) ?? false }), + let indexOfInputDate = defaultDays.firstIndex(where: { $0.date?.kvkIsSameDay(otherDate: data.date) ?? false }), let firstDate = defaultDays.first?.date { let extraBufferDays = (defaultDays.count - indexOfInputDate) % maxDays if extraBufferDays > 0 { var i = extraBufferDays while (i > 0) { - if let newDate = firstDate.addingTo(.day, value: -1 * i) { + if let newDate = firstDate.kvkAddingTo(.day, value: -1 * i) { extensionDays.append(Day(type: .empty, date: newDate, data: [])) } i -= 1 diff --git a/Sources/KVKCalendar/YearCell.swift b/Sources/KVKCalendar/YearCell.swift index 8643f4b3..c621a52d 100644 --- a/Sources/KVKCalendar/YearCell.swift +++ b/Sources/KVKCalendar/YearCell.swift @@ -160,7 +160,7 @@ final class YearCell: UICollectionViewCell { } guard date?.kvkYear == nowDate.kvkYear else { - if date?.isEqual(selectDate) == true { + if date?.kvkIsEqual(selectDate) == true { label.textColor = style.year.colorSelectDate label.backgroundColor = style.year.colorBackgroundSelectDate label.layer.cornerRadius = label.frame.height / 2