patchthecode / JTAppleCalendar

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

Option to avoid toggle button behaviour on multiple selection #98

Closed soniacasas closed 8 years ago

soniacasas commented 8 years ago

HI!

First of all, amazing work! This is really a piece of art of code!

I want to achieve this behaviour that I saw on the examples thread here

I have an array with some range of dates, so i'm doing

for leave in allLeavesReq {
    calendarView.selectDates(from: leave.fromDate!, to: leave.toDate!, triggerSelectionDelegate: false)
}

Checking the code of selectDates(from startDate:NSDate, to endDate:NSDate, triggerSelectionDelegate: Bool = true) { selectDates(generateDateRange(from: startDate, to: endDate), triggerSelectionDelegate: triggerSelectionDelegate) I noticed this

...
else { // If multiple selection is on. Multiple selection behaves differently to singleselection. It behaves like a toggle.

    if self.theSelectedIndexPaths.contains(sectionIndexPath) { // If this cell is already selected, then deselect it
        deSelectTheDate(sectionIndexPath)
    } else {
        // Add new selections
        // Must be added here. If added in delegate didSelectItemAtIndexPath
        selectTheDate()
    }
}

This is making that if a date is previous selected it will be deselected, and cellSelectionChanged is called with isSelected on false, but to add the lines of the example I need to avoid that toggle behaviour.

Maybe is there a way to achieve this already? Do you have another approach to solve my problem?

PS: I try using calendar(calendar: JTAppleCalendarView, canDeselectDate date: NSDate, cell: JTAppleDayCellView, cellState: CellState) -> Bool and returning false but this didn't fix mi problem

Thanks again for the awesome work!

patchthecode commented 8 years ago

[EDITED] thanks :] OK. just so i understand the problem fully.

You have calendarView.allowsMultipleSelection = true And you wish to select a range of dates.

And, If the date that you are trying to select is already selected, you want it to remain selected when you call this function?

  1. You can call generateDateRange(from startDate: NSDate, to endDate:NSDate) to generate the array of dates. Then simply remove the dates that are already selected from that array. You can know which dates are already selected by calling calendarView.selectedDates. When this is done, you will have an array of dates that are not selected as yet. You can then call calendarView.selectDates(theArray) to select the date range.
  2. You can also first deselect the dates that is already selected. And then select the dates in the range that you want selected.

what are your thoughts on this?

patchthecode commented 8 years ago

Hi I have made an upgrade to the JTAppleCalendar library.

If you are using this library with cocoapods, then can you follow these instructions on question 8 to test it?

soniacasas commented 8 years ago

Hi! I tested and it works, the selected days remain selected!

But unfortunately this just fix a part of my problem.

I'm gonna try to explain myself the best I can, maybe you can help me find and approach :]

I need to make a leaves calendar, so I need to mark in te calendar (with bars, as you can see on the example) a range of dates, that are the leave days of some other people. Sometimes you have 2 or more people on leaves at the same time, so I need to show that with the bars.

This is an example of what i want to achieve

screen shot 2016-08-03 at 09 41 34

The biggest problem I think is on dates after October 7th, because is a date selected just once, but the red bar started on the third position and it needs to continue in that position.

Maybe I just need to store in the calendar what cells are selected and what bars are on/off and notify the cell what bars have to show, and keep all the logic in the calendar.

Sorry for the troubles!

Thanks a lot!

patchthecode commented 8 years ago

OK, I am not sure I fully understand what you are trying to achieve. What do you want happen to the red bar after the 7th?

soniacasas commented 8 years ago

How do I know to show the bar in the third position? in other words how do i know that bar is a continuation of the previous one?

On day 5 you can notify the cell that he needs to show 3 bars, because the date is contained 3 times on my array of dates... and on day 6 I notify the cell he need to show 2, but in what order?

The only way i'm figure it out is get the all the cells that represents the dates of the range and set the bar to ON

I make this peace of code that maybe can make me explain better

//Leaves Req are sorted <
for leave in allLeavesReq {

// I want to get the cellView of a date, The way I found it is first get the cell status
            let cellStateOfFirstDay = calendarView.cellStatusForDate(leave.fromDate!)
// Then I can call cell() that is a JTAppleDayCell (This is always nil) and then get is content view (JTAppleDayCellView) 
            if let cell = cellStateOfFirstDay?.cell(), let startCell = cell.contentView as? CellView {
//I ask the cell for which bars are ON and returns me the position of the next free bar
                let position = startCell.nextFreeBar()
//Here I make a for-in for all the dates in the range, get the current date's cell and call a method to show the bar in the position i want.
                for currentDate in calendarView.generateDateRange(from: leave.fromDate!, to: leave.toDate!) {
                    let cellStateOfCurrentDate = calendarView.cellStatusForDate(currentDate)
                    if let cell = cellStateOfCurrentDate?.cell(), let cellViewOfCurrentDate = cell.contentView as? CellView {
                        cellViewOfCurrentDate.showBarInPosition(position, withColor: UIColor.purpleColor())
                    }
                }
            }
        }

I'm not really sure if thats the best way to do it, and maybe i'm being a headache for you!

forgive me!

Thanks a LOT!

patchthecode commented 8 years ago

if you are online. Join me here

patchthecode commented 8 years ago

Ok, if im not mistaken, I think you might be doing something wrong. Why are you running a loop to change the content of the cell like this?

JTAppleCalendar is like a UITableView.

In a UITableview, you have a cellForRowAtIndexPath: function. In that function you setup the cells that are going to be displayed on the UITableView.

in JTAppleCalendar, you have this function:

calendar(calendar: JTAppleCalendarView, isAboutToDisplayCell cell: JTAppleDayCellView, date: NSDate, cellState: CellState)

In this function (just like a UITableView), you get the dateCells for you to manipulate. In a UITableView, you would not be looping over the cells to change them right? So in JTAppleCalendar, you should not do this as well.

You have your dataSource which is an array of Leaves. So use this dataSource in combination with the delegate function (posted above) to update the look of your cell, just like you would in a UITableView.

You can take a look at the example project attached to this repository. Or you can also take a look at the Tutorial here. I hope I understood your question?

patchthecode commented 8 years ago

I will close this issue as the original calendar enhancement is resolved. If you have any non-calendar related issues you can always chat here anytime 👍

If you have a new calendar issue/bug/enhancement then lets create a new issue for it. Thanks.