diff --git a/JTAppleCalendar.xcodeproj/project.pbxproj b/JTAppleCalendar.xcodeproj/project.pbxproj index dfc45cb6..35d4a043 100644 --- a/JTAppleCalendar.xcodeproj/project.pbxproj +++ b/JTAppleCalendar.xcodeproj/project.pbxproj @@ -356,7 +356,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = GBBYECNDQ9; + DEVELOPMENT_TEAM = D35B5Y6JX8; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; @@ -384,7 +384,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = GBBYECNDQ9; + DEVELOPMENT_TEAM = D35B5Y6JX8; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; diff --git a/Sources/JTAppleCalendar/JTACInteractionMonthFunctions.swift b/Sources/JTAppleCalendar/JTACInteractionMonthFunctions.swift index 43a1cf31..9e97b5ce 100644 --- a/Sources/JTAppleCalendar/JTACInteractionMonthFunctions.swift +++ b/Sources/JTAppleCalendar/JTACInteractionMonthFunctions.swift @@ -498,6 +498,74 @@ extension JTACMonthView { } else if yOffset >= contentSize.height - frame.height { yOffset = contentSize.height - frame.height } + + // This was needed for when the user scrolls to next segment which will be the last, + // then the value is not exact the same as the height of the content, + // and then the didScrollToSegment delegate got called before the scroll happened, this fixed it. + + yOffset = yOffset.rounded() + } + + // Get valid indexPath of date to scroll to + + // This code is needed so that when we call the delegate we can give it the right DateSegmentInfo + var date: Date + let visibleDatesTMP = visibleDates() + + switch destination { + case .start: + date = startDateCache + case .end: + date = endDateCache + case .next: + let nextDate = visibleDatesTMP.outdates.last?.date ?? endDateCache + + // We add 5 days so that we are sure, that we are in the month + // (month end and start dates can sometimes result in wrong DateSegmentInfo) + let correctedNextDate = calendar.date(byAdding: .day, value: 5, to: nextDate) ?? endDateCache + + // If we added maybe too much days we check if we are in the range of the calendar + // if we gone too far we just use the endDate of the Calendar + if correctedNextDate < endDateCache + { + date = correctedNextDate + } + else + { + date = endDateCache + } + + case .previous: + + let prevDate = visibleDatesTMP.indates.first?.date ?? startDateCache + + // Same happens here, but because we want the previous month/segment we substract 5 days + let correctedPrevDate = calendar.date(byAdding: .day, value: -5, to: prevDate) ?? startDateCache + + // Same check happens here, if we are below the date range, we just use the startDate + if correctedPrevDate > startDateCache + { + date = correctedPrevDate + } + else + { + date = startDateCache + } + } + + let retrievedPathsFromDates = pathsFromDates([date]) + if retrievedPathsFromDates.isEmpty { return } + let sectionIndexPath = pathsFromDates([date])[0] + + guard let point = targetPointForItemAt(indexPath: sectionIndexPath) else { + assert(false, "Could not determine CGPoint. This is an error. contact developer on github. In production, there will not be a crash, but scrolling will not occur") + return + } + + let dateSegmentInfo = datesAtCurrentOffset(point) + + if triggerScrollToDateDelegate { + calendarDelegate?.calendar(self, willScrollToDateSegmentWith: dateSegmentInfo) } scrollTo(point: CGPoint(x: xOffset, y: yOffset), @@ -536,8 +604,8 @@ extension JTACMonthView { // Set triggereing of delegate on scroll self.triggerScrollToDateDelegate = triggerScrollToDateDelegate - - // Ensure date is within valid boundary + + // Ensure date is within valid boundary let components = calendar.dateComponents([.year, .month, .day], from: date) let firstDayOfDate = calendar.date(from: components)! if !((firstDayOfDate >= startOfMonthCache!) && (firstDayOfDate <= endOfMonthCache!)) { return } @@ -551,7 +619,12 @@ extension JTACMonthView { assert(false, "Could not determine CGPoint. This is an error. contact developer on github. In production, there will not be a crash, but scrolling will not occur") return } - + + if self.triggerScrollToDateDelegate == true { + let dateSegmentInfo = datesAtCurrentOffset(point) + self.scrollViewWillBeginDragging(self, visibleDates: dateSegmentInfo) + } + scrollTo(point: point, triggerScrollToDateDelegate: triggerScrollToDateDelegate, isAnimationEnabled: animateScroll, diff --git a/Sources/JTAppleCalendar/JTACMonthViewProtocols.swift b/Sources/JTAppleCalendar/JTACMonthViewProtocols.swift index d65df022..04da730d 100644 --- a/Sources/JTAppleCalendar/JTACMonthViewProtocols.swift +++ b/Sources/JTAppleCalendar/JTACMonthViewProtocols.swift @@ -138,6 +138,9 @@ public protocol JTACMonthViewDelegate: class { /// Informs the delegate that the user just lifted their finger from swiping the calendar func scrollDidEndDecelerating(for calendar: JTACMonthView) + /// Informs the delegate that the scrolling animation concludes + func scrollDidEndScrollingAnimation(for calendar: JTACMonthView) + /// Tells the delegate that a scroll occured func calendarDidScroll(_ calendar: JTACMonthView) @@ -178,4 +181,5 @@ public extension JTACMonthViewDelegate { func calendarSizeForMonths(_ calendar: JTACMonthView?) -> MonthSize? { return nil } func sizeOfDecorationView(indexPath: IndexPath) -> CGRect { return .zero } func scrollDidEndDecelerating(for calendar: JTACMonthView) {} + func scrollDidEndScrollingAnimation(for calendar: JTACMonthView) {} } diff --git a/Sources/JTAppleCalendar/JTACScrollViewDelegates.swift b/Sources/JTAppleCalendar/JTACScrollViewDelegates.swift index ec2d7290..d38fe8e3 100644 --- a/Sources/JTAppleCalendar/JTACScrollViewDelegates.swift +++ b/Sources/JTAppleCalendar/JTACScrollViewDelegates.swift @@ -198,6 +198,10 @@ extension JTACMonthView: UIScrollViewDelegate { DispatchQueue.main.async { // https://github.com/patchthecode/JTAppleCalendar/issues/778 self.executeDelayedTasks(.scroll) } + + DispatchQueue.main.async { + self.calendarDelegate?.scrollDidEndScrollingAnimation(for: self) + } } /// Tells the delegate that the scroll view has @@ -207,8 +211,16 @@ extension JTACMonthView: UIScrollViewDelegate { self.calendarDelegate?.calendar(self, didScrollToDateSegmentWith: dates) } } - - /// Tells the delegate that a scroll occured + + /// Tells the delegate when a scrolling animaton + /// in the scroll view begins + public func scrollViewWillBeginDragging(_ scrollView: UIScrollView, visibleDates: DateSegmentInfo) { + if let shouldTrigger = triggerScrollToDateDelegate, shouldTrigger == true { + self.calendarDelegate?.calendar(self, willScrollToDateSegmentWith: visibleDates) + } + } + + /// Tells the delegate that a scroll occured public func scrollViewDidScroll(_ scrollView: UIScrollView) { calendarDelegate?.calendarDidScroll(self) }