Skip to content

Common Questions

JTAppleCalendar edited this page Jul 28, 2016 · 51 revisions
  1. How do I disable a Date from being tapped? / How do I make dates invisible?
  2. How do I set the number of rows per month to 4 or 5?
  3. How do I add a section header?
  4. I have some dates from a server, how do I have them selected before my application starts?
  5. Common reloading patterns
  6. Help!! I seem to have some extra space shown above my calendar view.
  7. [Is it possible to show two months on the same screen?][#7]
  8. How do I test your latest code to see if my bug is fixed there?

1

How do I disable a Date from being tapped? / How do I make dates invisible?

It's pretty much the same as any UIView. You can disable a cell by setting userInteractionEnabled of the CalendarCell to true or false.

userInteractionEnabled = false

So let's say youre in the month of April, and you do not want a user to select the gray colored dates in the previous month of March or the gray colored dates in the future month of May, you can do the following.

// Assuming you're inside the CellView.swift class in the sample app
if cellState.belongsTo = .ThisMonth {
   self.userInteractionEnabled = true
} else {
   self.userInteractionEnabled = false
}

Cells can also be made hidden with the same approach. Just set the view's hidden property to false. The following line of code will only hide dates belonging to the previous month.

if cellState.dateBelongsTo == .PreviousMonthWithinBoundary {
    self.hidden = false
} else {
    self.hidden = true
}
  • .ThisMonth = the date to be displayed belongs to the month section
  • .PreviousMonthWithinBoundary = date belongs to the previous month, and it is within the date boundary you set
  • .PreviousMonthOutsideBoundary = date belongs to previous month, and it is outside the boundary you have set
  • .FollowingMonthWithinBoundary = date belongs to following month, within boundary
  • .FollowingMonthOutsideBoundary = date belongs to following month, outside boundary

2

How do I set the number of rows per month to 4 or 5?

You can't. The calendar displays 1, 2, 3 & 6 rows. Setting it to 4 or 5, forcefully resets it to 6.

And why? Because sometimes a month can take up 6 rows maximum.

  • If you set it to 1, then 6 is divisible by 1. Therefore, there will be 6 single rows to display the month.
  • If you set it to 2, then 6 is divisible by 2. Therefore, there will be 3 double rows to display the month.
  • Setting to 3 means, 2 triple rows displayed to display a month.
  • Setting to six means 1 single 6 row section to display a month.

If you have any suggestions on how this can be improved, let me know by opening an issue. If you really do not want to display the 6 then you can simply hide the 6th row when needed. Hiding is as simple as checking the cellState.

// Assuming youre in the cellView class of the sample app provided on Github.
if cellState.row == 6 {
   self.hidden = true
}

NOTE: there is an updatecoming where you can disable the calendar from generating unnecessary end rows. So lets say your month has 5 rows, it will display 5. But if your month has 6 rows, it will display 6. This update is coming soon, but in the mean time, use the methods shown above, or open an issue and I will try to find a better solution for you.

3

How do I add a section header?

If you are adding section headers you do it as follows:

  1. create a yourCustomHeader.xib file and design it how ever you want. Follow the same steps for creating the custom cell shown in the the Getting Started tutorial. The only difference is that the view should be a subclass of JTAppleHeaderView. All other steps is the same

  2. Register your class just like you did the cell in the tutorial.

calendarView.registerHeaderViewXibs(fileNames: ["PinkSectionHeaderView"])
  1. Finally, If youre registering only one header, then you must implement the following 2 delegate methods:
func calendar(calendar: JTAppleCalendarView, sectionHeaderSizeForDate date: (startDate: NSDate, endDate: NSDate)) -> CGSize 
func calendar(calendar: JTAppleCalendarView, isAboutToDisplaySectionHeader header: JTAppleHeaderView, date: (startDate: NSDate, endDate: NSDate), identifier: String)

If you registered more than one header however, you must implement additional method:

func calendar(calendar: JTAppleCalendarView, sectionHeaderIdentifierForDate date: (startDate: NSDate, endDate: NSDate)) -> String?

4

I have some dates from a server, how do I have them selected before my application starts?

You can have them selected by using the selectDate function.

self.calendarView.selectDates([NSDate()])

Keep in mind that this function triggers the didSelect delegate. Sometimes, you may not want this delegate to be called. In that case you can use the other options of this same function.

self.calendarView.selectDates([NSDate()], triggerSelectionDelegate: false)

Note: If you called a calendarView.reloadData() function, and you want to do a selection right afterward. Then doing it like the following will not work properly:

// Common mistake
calendarView.reloadData()
self.calendarView.selectDates([NSDate()])

This may not work because reloadData() occurs on another thread. Below is the proper way

// Proper way
calendarView.reloadData() {
    self.calendarView.selectDates([NSDate()])
}

5

Common reloading patterns

  1. No scrolling on viewDidload(). We just want to setup our labels with the current date
override func viewDidLoad() {
...
    calendarView.reloadData()
    let currentDate = self.calendarView.currentCalendarDateSegment()
}
  1. We just reloaded the calendarView. We want to scroll to a particular date
override func viewDidLoad() {
...
    calendarView.reloadData()
    // You can do any of the following based on your needs

    //1. This automatically triggers your delegates
    calendarView.scrollToDate(myDate) 

    //2. Self explanatory. 
    calendarView.scrollToDate(myDate, triggerScrollToDateDelegate: false)

    //3. After we reload, we may want to scroll to a date and run some code when scrolling completes.
    //   If code needs to be run after the scrolling, it must be placed in the trailing closure
    calendarView.scrollToDate(myDate, triggerScrollToDateDelegate: false){
        let currentDate = self.calendarView.currentCalendarDateSegment()
    }
}
  1. You can also accomplish the same as above with the following code
calendarView.reloadData(withAnchorDate: myDate){
    let currentDate = self.calendarView.currentCalendarDateSegment()
}

6

Help!! I seem to have some extra space shown above my calendar view.

If this does not solve your problem, then let me know -> https://github.com/patchthecode/JTAppleCalendar/issues/31#issuecomment-222337818

7

Is it possible to show two months on the same screen?

This would mean that you wish to make your date cells smaller. Try using the following property:

let someSmallerDateCellValue = 20
calendarView.itemSize = someSmallerDateCellValue

8

How do I test your latest code to see if my bug is fixed there?

To test the master branch with your current project do this:

Go to your pod file, and change your JTAppleCalendar pod to this:

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

Then do a:

pod install
Clone this wiki locally