You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Thank you all for this great library which helps a lot in my current project!
I got a problem in my project today and I traced it down to a floating point rounding problem in JtAppleCalendar.
I found that targetPointForItemAt as defined in JTACMonthQueryFunctions.swift (extension JTACMonthView) will not work for all calendar width values if you use scrollingMode = stopAtEachCalendarFrame.
Reason is that you will get floating point rounding errors when using floor(frameSection) in line 67:
// Determines the CGPoint of an index path. The point will vary depending on the scrollingMode
func targetPointForItemAt(indexPath: IndexPath, preferredScrollPosition: UICollectionView.ScrollPosition? = nil) -> CGPoint?
...
switch scrollingMode {
case .stopAtEachCalendarFrame, .stopAtEach, .nonStopTo:
let frameSection = theTargetContentOffset / fixedScrollSize
let roundedFrameSection = floor(frameSection)
if scrollDirection == .horizontal {
x = roundedFrameSection * fixedScrollSize
} else {
// vertical is fixed scroll segments because here, we're using stop at frame and custom fixed size
y = roundedFrameSection * fixedScrollSize
}
Say you are at indexPath.section = 66,
your fixedScrollSize is 344.3333333333333 for whatever reason (it is in my case) and
your theTargetContentOffset = 22725.99999999999
then frameSection will be 65.99999999999997 (but should be 66) and
the roundedFrameSection = floor(frameSection) will be 65
which is off 1 section or page however you call it.
So for scrollingMode = stopAtEachCalendarFrame it would be much easier to change the code starting line 64 in file JTACMonthQueryFunctions.swift to:
switch scrollingMode {
case .stopAtEachCalendarFrame:
if scrollDirection == .horizontal {
x = CGFloat(indexPath.section) * fixedScrollSize
} else {
y = CGFloat(indexPath.section) * fixedScrollSize
}
case .stopAtEachSection, .nonStopToSection:
Because all the calculation does is finding the section number to scroll to...
You probably could also simplify the other scrollingModes, because in those cases fixedScrollSize would be the same as theTargetContentOffset, so the result would always be 1, but I have not tested these.
What do you think?
The text was updated successfully, but these errors were encountered:
markusfi
changed the title
Foating point rounding error when using crollingMode = stopAtEachCalendarFrame
Foating point rounding error when using scrollingMode = stopAtEachCalendarFrame
Apr 21, 2020
markusfi
pushed a commit
to markusfi/JTAppleCalendar
that referenced
this issue
Apr 21, 2020
It seems this is more complicated than I thought and my proposed changes will not solve this issue, but introduce some other problems when scrolling...
Thank you all for this great library which helps a lot in my current project!
I got a problem in my project today and I traced it down to a floating point rounding problem in JtAppleCalendar.
I found that targetPointForItemAt as defined in JTACMonthQueryFunctions.swift (extension JTACMonthView) will not work for all calendar width values if you use scrollingMode = stopAtEachCalendarFrame.
Reason is that you will get floating point rounding errors when using floor(frameSection) in line 67:
Say you are at indexPath.section = 66,
your fixedScrollSize is 344.3333333333333 for whatever reason (it is in my case) and
your theTargetContentOffset = 22725.99999999999
then frameSection will be 65.99999999999997 (but should be 66) and
the roundedFrameSection = floor(frameSection) will be 65
which is off 1 section or page however you call it.
So for scrollingMode = stopAtEachCalendarFrame it would be much easier to change the code starting line 64 in file JTACMonthQueryFunctions.swift to:
Because all the calculation does is finding the section number to scroll to...
You probably could also simplify the other scrollingModes, because in those cases fixedScrollSize would be the same as theTargetContentOffset, so the result would always be 1, but I have not tested these.
What do you think?
The text was updated successfully, but these errors were encountered: