Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

trigger willScrollToDateSegmentWith when scrolling programmatically with scrollToSegment #1327

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
4 changes: 2 additions & 2 deletions JTAppleCalendar.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = GBBYECNDQ9;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't need

DEVELOPMENT_TEAM = D35B5Y6JX8;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
Expand Down Expand Up @@ -384,7 +384,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = GBBYECNDQ9;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't need

DEVELOPMENT_TEAM = D35B5Y6JX8;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
Expand Down
79 changes: 76 additions & 3 deletions Sources/JTAppleCalendar/JTACInteractionMonthFunctions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty line

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can change to:

date = correctedNextDate < endDateCache ? 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),
Expand Down Expand Up @@ -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 }
Expand All @@ -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,
Expand Down
4 changes: 4 additions & 0 deletions Sources/JTAppleCalendar/JTACMonthViewProtocols.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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) {}
}
16 changes: 14 additions & 2 deletions Sources/JTAppleCalendar/JTACScrollViewDelegates.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
}
Expand Down