patchthecode / JTAppleCalendar

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

Simple Way To Write Infinite Scrolling? #585

Closed magicbysunlight closed 6 years ago

magicbysunlight commented 6 years ago

hello,

was gonna send an email but your thing said just open an issue

anyway I've been writing stuff to calculate new start and end dates, but was wondering if there was a simple way to

1 write infinite scrolling to the future and past 2 when view did load setting the content offset of the calendar view to the date of today 3 call a function to scroll to a date

I've also forked the file; I'm not that good at coding yet but as I was reading through it I've been spellchecking the comments to have you pull later :)

thanks jay

magicbysunlight commented 6 years ago

https://github.com/geoffreygonzales/Honeydew

I think the solution would be to use anchor date but idk how to implement it :(

patchthecode commented 6 years ago
  1. write infinite scrolling to the future and past This calendar does not have infinite scrolling by default, but there are some developers who have implemented it in their projects (i can look this up for you)

  2. when view did load setting the content offset of the calendar view to the date of today In your viewDidLoad() function, simply call calendarView.scrollToDate(myDate) and if you dont want any animation, call calendarView.scrollToDate(myDate, animateScroll: false)

  3. call a function to scroll to a date Do the same thing as in question # 2

magicbysunlight commented 6 years ago

thank you

I have a function that automatically sets start and end date a at runtime b whenever an individual lifts their scrolling finger && the content offset is close to the start or end

after that, would it be best to call

calendarView.reloadData()

and then

calendarView.scrollToDate(currentDateInView, animateScroll: false) ?

patchthecode commented 6 years ago

That should work. but how about reload with this instead? calendarView.reloadData(withAnchor: myDate)

magicbysunlight commented 6 years ago

perfect perfect perfect thank you very much.

also : on initial configuration of the calendar, where you set start and end dates, is there a similar way to load at a specified date?

1 when the app loads initially, the dates and other configurations are set, 2 then the view shows (briefly the start date month) 3 then, since I call scrollToDate(toDate, animateScroll : false) - it shows the specified date.

is there a way to skip / set step 2, for the initial launch of the app? (since if I call reload data here it crashes)

patchthecode commented 6 years ago

@geoffreygonzales sounds like a bug to me.

Can you put this in your Podfile and do a pod update ?

pod 'JTAppleCalendar', :git => 'https://github.com/patchthecode/JTAppleCalendar.git', :branch => 'master'

This version will be release in about a week or so. Keep in mind that it will force you to implement the willDisplayCell function This issue explains how you should setup the willDisplay cell and the cellForItem function in this master branch -> https://github.com/patchthecode/JTAppleCalendar/issues/553

Let me know if step 2 goes away when you scroll to date on viewDidLoad()

magicbysunlight commented 6 years ago

I'm getting this error when running pod update

[!] There are multiple dependencies with different sources for JTAppleCalendar in Podfile:

magicbysunlight commented 6 years ago

this not a primary issue for me, as the 100ms view of the startDate of the calendar before the scrollToDate is not even seen by individuals, as the calendar is initially hidden until toggled

so no pressure :)

I have another question about setting the size and position of the calendar programmatically: I call this when viewDidLayoutSubviews (doesn't work in view did load)

func setCalendarSizeAndPosition()
{    
      // Get Screen Properties
      let screenWidth = UIScreen.main.bounds.width
      let screenHeight = UIScreen.main.bounds.height

      // Set Size And Position Properties
      let calendarWidth = screenWidth * 0.85625
      let calendarHeight = screenHeight * 0.630281690140845

      let calendarX = (screenWidth / 2) - (calendarWidth / 2)
      let calendarY = screenHeight * 0.419014084507042

      // Set The Global Variable For Resting The Calendars Resting Y Position
      calendarRestingPosition = calendarY

      // Set Calendar Size And Position
      calendarView.frame.size.width = calendarWidth
      calendarView.frame.size.height = calendarHeight

      calendarView.frame.origin.x = calendarX
      calendarView.frame.origin.y = calendarY
}

I use this when toggling the calendar

// Hides The Calendar Below The Screen
func putCalendarToSleep()
{
      UIView.animate(withDuration: 0.08)
            {
            self.calendarContentView.frame.origin.y += self.calendarContentView.frame.size.height
            }
}

// Shoes The Calendar Below The Screen
func wakeCalendarUp()
{
      UIView.animate(withDuration: 0.08)
            {
            self.calendarContentView.frame.origin.y -= self.calendarContentView.frame.size.height
            }
}

this is the behavior I experience:

0 during viewDidLayoutSubViews, I call setCalendarSizeAndPosition() and another function to hide it below the screen, until I call wakeCalendarUp()

1 when setCalendarSizeAndPosition() is called on view did load, does not resize and reposition the calendar it does work when put in viewDidLayoutSubViews tho

2 I have a button that toggles wakeCalendarUp() and putCalendarToSleep this repositions the calendar successfully

3 at the end of the 1st scroll, when finger is lifted off the screen, the calendar resizes and repositions itself to the size and position that it was at during didLayoutSubviews

EDIT: the culprit - label2.text = "\(today)" was in didEndDecelerating for some reason this RECALLS didLayoutSubviews, which has setCalendarSizeAndPosition() and another function to hide it below the screen. so it calls them again sometimes when the didScrollToDateSegmentWith is called, is does a thing where it loops didLayoutSubviews 5 or 6 times. when label2.text = "asdf" is removed, it does not call didLayoutSubviews and there are no problems

maybe the framework does something during viewDidLayoutSubviews that is view related, as since the view has not appeared yet, it delays viewDidLayoutSubviews until after viewDidAppear - when I put the code in there it was overwritten.

I think the solution for this would be a better way to programmatically alter height width x and y that the framework has set somewhere bc it uses these to reset those values every time didLayoutSubviews is called

I also cant do it in interface builder with precision bc of apples dumb size class thingy that no longer allows for device specific constraints.

patchthecode commented 6 years ago

will look at this in the morning.

magicbysunlight commented 6 years ago

I pushed a project that recreated the bug

1 try with the label.text = "" commented out 2 try with label.text = "" left in

watch the console

hope this helps :)

patchthecode commented 6 years ago

@geoffreygonzales Hey, may i get a link to that project please?

magicbysunlight commented 6 years ago

oops I thought I pasted it

https://github.com/geoffreygonzales/calendar-test

magicbysunlight commented 6 years ago

I made another branch called branch2

it initially sets the y position of the calendar below the view, and the buttons show and hide it fine but when its shown then scrolled - it blips out.

the console shows it call View Will Layout Subviews like a billion times it does this a few times when trying to scroll, then it stops and works fine

EDIT I’m still a noob dev, and have no idea how the calendar framwork works, but maybe this will help http://aplus.rs/2015/uicollectionviewcell-woes-with-bounds-change/

patchthecode commented 6 years ago

The calendar is a UICollectionView subclass. It behaves exactly the same as a UICollectionView would. I looked at you code, but I couldnt understand it very well.

Also note that, any change you make to the calendar that results in a change in the UICOllectionView layout, it will invalidate the layout.

Are you just trying to show and hide the calendar? If this is what you need to do then we can get this done in a lot less code.

magicbysunlight commented 6 years ago

Oh really? I thought I was being simple with the code. oops

I’m trying to accomplish

1 calculate the size and width of the calendar and it’s days of week and it’s container based on the uiscreen.main.bounds.height on the initial app load 2 calendar initially below / hidden on the app load programmatically with step 1 3 button that animates it up from the bottom - DONE 4 button that animates it down - DONE 5 selecting a date returns a date object

the main issue I’m running into is after animating it up from the bottom, and then scrolling - it calls layout sub views and goes all crazy and it docent scroll it just hides below the screen. Is that what you mean by the layout gets invalidated? because it’s position and size were changed and saved below the screen?

thanks for the support so far!

patchthecode commented 6 years ago

the main issue I’m running into is after animating it up from the bottom, and then scrolling - it calls layout sub views and goes all crazy and it docent scroll it just hides below the screen. Is that what you mean by the layout gets invalidated? because it’s position and size were changed and saved below the screen?

No. By invalidation I meant this -> From Apple docs

If your calendar is hiding below the screen, then maybe there is something in the code doing this? The library doesn't have any animation or default moving of frames.

For instance, i did a inspect on your views. The calendar's Y position is well beneath the height of the size of your view.

screen shot 2017-10-14 at 5 32 13 pm

I think you need to double check by how much exactly you are moving the calendar's frame. The image above was taken from your branch 2 code.

magicbysunlight commented 6 years ago

I solved animating it up and down. I put it in a sub view and then I animate the sub view :)

We’re you able to run and try scrolling on branch 2?

patchthecode commented 6 years ago

Yes. I posted the image of the results on branch 2. Above. The calendar was hidden making it impossible to scroll.

magicbysunlight commented 6 years ago

Could you use the buttons to animate it up and down?

EDIT : Oh I didn't know you could inspect like that; I thought that was just the interface builder.

Try it on the iPhone 5s please, because I haven't yet implemented it automatically resizing at build time

patchthecode commented 6 years ago

I just did. The result is the same. The calendar is hidden. I will close this issue for now, as it seems to be errors with the hiding of the calendar and not related to the calendar directly.

But yes you can inspect your calendar by clicking on at the bottom of the screen.->

screen shot 2017-10-15 at 12 27 45 pm
magicbysunlight commented 6 years ago

I pushed an update on branch2 if you want to check out the scrolling