patchthecode / JTAppleCalendar

The Unofficial Apple iOS Swift Calendar View. Swift calendar Library. iOS calendar Control. 100% Customizable
https://patchthecode.com
MIT License
7.55k stars 806 forks source link

Question on displaying vertical scrolling calendar with headers. #850

Open ThasneemH opened 6 years ago

ThasneemH commented 6 years ago

Hi,

Thanks for making this really neat calendar framework, very helpful.

I am using the latest version 7.1.5 .This is more of a question of how to than an issue. Not sure where to post such queries, hence opening it as an issue.

I have a vertical scrolling calendar ( number of rows is 6) with headers enabled. The headers have a fixed height of 44.0 each. The scrolling mode is .stopAtEachSection . As per the current implementation, when headers are enabled , the calendar shows the header also when displaying each section. However, I would like to display only the dates for the month and the section headers will show only while scrolling. ( Similar to the month view on the iPhone calendar app).

In UIScrollViewDelegates.swift , I tried to adjust the offsets, based on the header height of 44 as in the snippet below. ( Also on startup of the calendar, I call scrollToHeaderForDate: with an extraAddedOffset of 44) . Although this achieves what I am trying to do, there is one issue. When the user doesn't do a full scroll ( lifts the finger after a short distance immediately, then it should scroll back to the same section that was being displayed and should not scroll to the previous or next section). However, with my changes for the offset, even after a slight change, it scrolls to to the next or previous sections ( based on the direction).

Is there any other place to adjust the offset to prevent this from happening or is there a more elegant way to achieve what I am trying to do? Have attached a snap shot of the native iOS calendar look that I am trying to achieve. Thanks very much for your help.

    case .stopAtEachSection:
        var calculatedOffSet: CGFloat = 44.0//0
        if scrollDirection == .horizontal ||
            (scrollDirection == .vertical && !calendarViewLayout.thereAreHeaders && cachedConfiguration.generateOutDates == .tillEndOfGrid) {
            // Horizontal has a fixed width.
            // Vertical with no header has fixed height
            let interval = calendarLayout.sizeOfContentForSection(theCurrentSection)
            calculatedOffSet = calculatedCurrentFixedContentOffsetFrom(interval)
        } else {
            // Vertical with headers have variable heights.
            // It needs to be calculated
            let currentScrollOffset = scrollView.contentOffset.y
            let currentScrollSection = calendarLayout.sectionFromOffset(currentScrollOffset)
            var sectionSize: CGFloat = 0
            if isScrollingForward() {
                sectionSize = calendarLayout.sectionSize[currentScrollSection]
                calculatedOffSet = sectionSize  + 44
            } else {
                if currentScrollSection - 1  >= 0 {
                    calculatedOffSet = calendarLayout.sectionSize[currentScrollSection - 1] + 44
                }
            }
        }
        setTargetContentOffset(calculatedOffSet)
screen shot 2018-08-06 at 11 46 15 am
patchthecode commented 6 years ago

Hmm. thats an interesting one. WIll give this a second look over the weekend.

ThasneemH commented 6 years ago

Thanks very much for your reply, and for taking the time to look into it. Would be very helpful if we can have this resolved.

ThasneemH commented 6 years ago

Did you get a chance to look at this..would be good as well if you can give some pointers on where to look. . thanks very much

patchthecode commented 6 years ago

I have finally taken a look at that scroll function. What you are asking is similar to what someone else was asking for: https://github.com/patchthecode/JTAppleCalendar/pull/817

This requires a re-write of the way scrolling works in this library. I do need to re-write it, but as of now i do not have time with my work.

But basically, the function that needs a re-write is

open func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
  ....
}

located in the UIScrollViewDelegates.swift file. It determines what happens when a user lifts the finger after dragging, and it determines if the calendar would snap back or scroll to the next section. A re-write of that function with a pull request would be appreciated as i do not have much time now. But once i am free, i will take a look.

patchthecode commented 5 years ago

finally getting around back to this.

I thought of a way to accomplish this. I was wondering if is added a physicalScrollOffset value to the calendar.

If a developer sets this, then when ever a user scrolls the calendar, it will also +/- the physicalScrollOffset. This will enable you to accomplish stuff like this.

patchthecode commented 5 years ago

scratch that idea... nah. it wont work.

ThasneemH commented 5 years ago

Thanks for looking into this. Would be helpful if it can be resolved.

patchthecode commented 5 years ago

I made some update. This should be possible soon.

robertcrabtree commented 4 years ago

I struggled with this for a couple hours today but I ended up finding a workaround. All you need to do is adjust the calendar's top constraint so that it holds a negative value equal to the height of the section header. So if the height of your section header is 50 points, then the calendar's top constraint should have a value of -50.

rouuuge commented 3 years ago

I made some update. This should be possible soon.

Any updates to this feature?

patchthecode commented 3 years ago

hmm.. I dont think i ever got around to this. It required a rewrite i didnt have the time to do, and there wasnt really a demand for this :/ Maybe someone can help out here.

patchthecode commented 3 years ago

I have set the help wanted flag for this. Any one who wishes to do this can chip in.

If no one does, then I'll get to it, but not anytime soon.