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

Foating point rounding error when using scrollingMode = stopAtEachCalendarFrame #1248

Open
markusfi opened this issue Apr 21, 2020 · 1 comment

Comments

@markusfi
Copy link

markusfi commented Apr 21, 2020

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?

@markusfi 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
@markusfi
Copy link
Author

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...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant