0

I have a calendar, and I want to select an entire row (week) when I select a day.. this is my code so far:

//When a date is selected
func calendar(_ calendar: JTAppleCalendarView, didSelectDate date: Date, cell: JTAppleCell?, cellState: CellState) {

    selectTheWeek(of: date)
    setupLayoutCell(cell: cell, cellState: cellState)

}

func selectTheWeek(of date: Date) {
    let starOfTheWeek = date.startOfWeek()
    let endOfTheWeeK = date.endOfWeek()
    calendarCollectionView.selectDates(from: starOfTheWeek, to: endOfTheWeeK)
}

extension Date {
func startOfWeek() -> Date {
    let calendar = Calendar.autoupdatingCurrent
    let currentDateComponents = calendar.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self)
    return calendar.date(from: currentDateComponents)!
}

func endOfWeek() -> Date {
    let cal = Calendar.autoupdatingCurrent
    var component = DateComponents()
    component.weekOfYear = 1
    component.day = -1
    return cal.date(byAdding: component, to: startOfWeek())!
}
}

the problem is that I'm having an infinite loop, and it's clear the reason. But I don't know how to prevent it. Any help?

JTAppleCalender is an external library. It's an extension of a collectionView.

Amit
  • 4,837
  • 5
  • 31
  • 46
Andrea Miotto
  • 7,084
  • 8
  • 45
  • 70

3 Answers3

1

You can use 2 techniques to break the loop.

First:

calendarViewselectDates(from: starOfTheWeek, to: endOfTheWeeK, triggerSelectionDelegate: false)

By setting triggerSelectionDelegate to false, your delegate function didSelect will not be called.


Second:

If you are using MasterBranch code (which i'll be releasing in a week or so), you can know whether or not your selection is programmer initiated vs user initiated. You know this by --> cellState.

if cellState.selectionType == .programatic {
   // ignore stuff        
} else {
   // Do stuff
}

You can put this if statement in your shouldSelect function.

Just a coder
  • 15,480
  • 16
  • 85
  • 138
  • thank you, now I have different circles for the selected days, like the once you did in you tutorials. How could I make an entire row with rounded edge? – Andrea Miotto Oct 16 '17 at 15:20
  • 1. `let cellStatus = calendarView.cellStatus(for: myDate)` 2. `cellStatus.cell` gives you access to the cell to modify – Just a coder Oct 16 '17 at 15:24
  • i mean something like this: https://cloud.githubusercontent.com/assets/17156261/25841123/8c55b2e6-34bc-11e7-8500-c599312022ed.png – Andrea Miotto Oct 16 '17 at 15:29
  • Oh you are talking about range selection? https://patchthecode.github.io/RangeSelection/ > The documention there is for version 6.0, but converting it to version 7.0 should be easy. If you have more questions, then open an issue on github. I check my issues there more frequently than stackoverflow. – Just a coder Oct 16 '17 at 18:32
0

I know this is a not the best possible solution but it could work to avoid your issue

//When a date is selected
var shouldSelectWeek = true
func calendar(_ calendar: JTAppleCalendarView, didSelectDate date: Date, cell: JTAppleCell?, cellState: CellState) {
    if shouldSelectWeek{
        selectTheWeek(of: date)
        shouldSelectWeek = false
    }
    setupLayoutCell(cell: cell, cellState: cellState)


}

func selectTheWeek(of date: Date) {
    let starOfTheWeek = date.startOfWeek()
    let endOfTheWeeK = date.endOfWeek()
    calendarCollectionView.selectDates(from: starOfTheWeek, to: endOfTheWeeK)
}

extension Date {
    func startOfWeek() -> Date {
        let calendar = Calendar.autoupdatingCurrent
        let currentDateComponents = calendar.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self)
        return calendar.date(from: currentDateComponents)!
    }

    func endOfWeek() -> Date {
        let cal = Calendar.autoupdatingCurrent
        var component = DateComponents()
        component.weekOfYear = 1
        component.day = -1
        return cal.date(byAdding: component, to: startOfWeek())!
}
Tarek A.
  • 218
  • 2
  • 12
0

Just add a new boolean variable like var shouldIgnoreDateSelection = false and then you just do

func calendar(_ calendar: JTAppleCalendarView, didSelectDate date: Date, cell: JTAppleCell?, cellState: CellState) {
    if shouldIgnoreDateSelection == false {
        selectTheWeek(of: date)
    }
    setupLayoutCell(cell: cell, cellState: cellState)
}

func selectTheWeek(of date: Date) {
    let starOfTheWeek = date.startOfWeek()
    let endOfTheWeeK = date.endOfWeek()
    shouldIgnoreDateSelection = true
    calendarCollectionView.selectDates(from: starOfTheWeek, to: endOfTheWeeK)
    shouldIgnoreDateSelection = false
}
Ladislav
  • 7,223
  • 5
  • 27
  • 31