Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

selectDates(dateArray, triggerSelectionDelegate: true, keepSelectionIfMultiSelectionAllowed: true) got random selection when we scroll #1022

Closed
boungly opened this issue Mar 28, 2019 · 7 comments

Comments

@boungly
Copy link

boungly commented Mar 28, 2019

[I'm not sure if this problem was opened before]

I'm currently using the latest version of JTAppleCalendar.

The problem is that when i have the array of date (dateArray), I use the dateArray in calendarView.selectDates(dateArray, ..., ...). Then when i scroll the calendarView, the selection just go random everywhere.

Note
CalendarView is Vertical + Paging is disable.
image

when i scroll it goes like this
image

@jovdelfin01
Copy link

I have the same problem. Is there any solution to this?

@patchthecode
Copy link
Owner

without code, i cant tell anything.

  1. what is your cellForItemAtDate function?

@boungly
Copy link
Author

boungly commented Mar 29, 2019

@patchthecode

 func calendar(_ calendar: JTAppleCalendarView, cellForItemAt date: Date, cellState: CellState, indexPath: IndexPath) -> JTAppleCell {
        let cell = calendar.dequeueReusableJTAppleCell(withReuseIdentifier: calenderCellIdentifier, for: indexPath) as! CalenderCollectionViewCell
        cell.configCell(date: cellState.text)
        handleCalendarTextColor(cell: cell, cellState: cellState)
        return cell
    }

@patchthecode
Copy link
Owner

Can you show me code relavent to the visibility of your cells and how they work?
That function you provided also calls other functions.

What might help better is, have you taken a look at the sample applicaiton attached to this github project?

@boungly
Copy link
Author

boungly commented Mar 29, 2019

@patchthecode

I'll just paste the whole code here maybe it's better.

import UIKit
import JTAppleCalendar

class CalenderViewController: UIViewController {

@IBOutlet weak var calenderView: JTAppleCalendarView!
@IBOutlet weak var departureDateLabel: UILabel!
@IBOutlet weak var arrivalDateLabel: UILabel!
@IBOutlet weak var backButtonView: UIView!
@IBOutlet weak var applyButton: UIButton!

var dateFormatter = DateFormatter()
let millisecondPerDay = 86400000
let calenderHeaderIdentifier = "CalenderHeaderCollectionReusableView"
let calenderCellIdentifier = "CalenderCollectionViewCell"
let calenderCellSize: CGFloat = 50.0
let thisMonthColor: UIColor = .black
let outMonthColor: UIColor = .lightGray
let sundayColor: UIColor = .red
let selectedDateColor: UIColor = .white
let deSelectedDateColor: UIColor = .black
var dateArray: [Date] = [] {
    didSet {
        calenderView.selectDates(dateArray, triggerSelectionDelegate: true, keepSelectionIfMultiSelectionAllowed: true)
    }
}
var selectedStartDate: Date? = nil {
    didSet {
        print("Start: \(selectedStartDate)")
    }
}
var selectedEndDate: Date? = nil {
    didSet {
        print("End: \(selectedEndDate)")
    }
}
var isRangeSelection = false

override func viewDidLoad() {
    super.viewDidLoad()

    setupUI()
}

@IBAction func applyClick(_ sender: Any) {
    calenderView.deselectAllDates(triggerSelectionDelegate: true)
}

}

extension CalenderViewController {
private func setupUI() {
calenderView.register(UINib(nibName: calenderHeaderIdentifier, bundle: Bundle.main),
forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader,
withReuseIdentifier: calenderHeaderIdentifier)

    calenderView.selectDates([Date(), Date(millisecond: Date().millisecondsSince1970 + millisecondPerDay * 2)], triggerSelectionDelegate: true, keepSelectionIfMultiSelectionAllowed: true)
    
    self.calenderView.calendarDelegate = self
    self.calenderView.calendarDataSource = self
    self.calenderView.allowsMultipleSelection = true
    self.calenderView.isRangeSelectionUsed = true
    self.calenderView.minimumLineSpacing = 0
    self.calenderView.minimumInteritemSpacing = 0
    self.calenderView.cellSize = calenderCellSize

    applyButton.setupRoundedView()

    backButtonView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(backToHome)))
}

@objc private func backToHome() {
    self.dismiss(animated: true)
}

private func handleCalendarTextColor(cell: JTAppleCell, cellState: CellState) {
    guard let cell = cell as? CalenderCollectionViewCell else { return }

    if cellState.dateBelongsTo == .thisMonth {
        cell.dateLabel.textColor = thisMonthColor
    }else {
        cell.dateLabel.textColor = .clear
    }

    if cellState.day == .sunday {
        cell.dateLabel.textColor = sundayColor
    }

    if cellState.dateBelongsTo == .thisMonth, cellState.day != .sunday {
        cell.dateLabel.textColor = cellState.isSelected ? selectedDateColor : deSelectedDateColor
    }
}

private func handleCalenderSelection(cell: JTAppleCell, cellState: CellState) {
    guard let cell = cell as? CalenderCollectionViewCell else { return }

    if isRangeSelection {

    }


    cell.selectedView.isHidden = !cellState.isSelected

    guard let startDate = selectedStartDate else { return }
    if cellState.date == startDate {
        cell.selectedView.setupRoundedView()
        cell.selectedView.isHidden = !cellState.isSelected
    }

    guard let endDate = selectedEndDate else { return }
    if cellState.date == endDate {
        cell.selectedView.setupRoundedView()
        cell.selectedView.isHidden = !cellState.isSelected
    }
}

}

extension CalenderViewController: JTAppleCalendarViewDelegate {
func calendar(_ calendar: JTAppleCalendarView, cellForItemAt date: Date, cellState: CellState, indexPath: IndexPath) -> JTAppleCell {
let cell = calendar.dequeueReusableJTAppleCell(withReuseIdentifier: calenderCellIdentifier, for: indexPath) as! CalenderCollectionViewCell

    cell.configCell(date: cellState.text)
    handleCalendarTextColor(cell: cell, cellState: cellState)

    return cell
}

func calendar(_ calendar: JTAppleCalendarView, didSelectDate date: Date, cell: JTAppleCell?, cellState: CellState) {
    guard let cell = cell else { return }

    if cellState.dateBelongsTo != .thisMonth {
        return
    }

    if selectedStartDate == nil {
        selectedStartDate = date
    }else {
        if date <= selectedStartDate! {
            selectedStartDate = date
        }else {
            selectedEndDate = date
        }
    }

    if let startDate = selectedStartDate, let endDate = selectedEndDate {
        dateArray = calenderView.generateDateRange(from: startDate, to: endDate)
    }

    handleCalenderSelection(cell: cell, cellState: cellState)
    handleCalendarTextColor(cell: cell, cellState: cellState)
}

func calendar(_ calendar: JTAppleCalendarView, didDeselectDate date: Date, cell: JTAppleCell?, cellState: CellState) {
    handleCalenderSelection(cell: cell!, cellState: cellState)
    handleCalendarTextColor(cell: cell!, cellState: cellState)
}

func calendar(_ calendar: JTAppleCalendarView, willDisplay cell: JTAppleCell, forItemAt date: Date, cellState: CellState, indexPath: IndexPath) {

}

func calendar(_ calendar: JTAppleCalendarView, headerViewForDateRange range: (start: Date, end: Date), at indexPath: IndexPath) -> JTAppleCollectionReusableView {
    let header = calendar.dequeueReusableJTAppleSupplementaryView(withReuseIdentifier: calenderHeaderIdentifier, for: indexPath) as! CalenderHeaderCollectionReusableView

    dateFormatter.dateFormat = "MMMM yyyy"

    header.configHeader(headerTitle: dateFormatter.string(from: range.start))

    return header
}

func calendarSizeForMonths(_ calendar: JTAppleCalendarView?) -> MonthSize? {
    return MonthSize(defaultSize: 50)
}

}

extension CalenderViewController: JTAppleCalendarViewDataSource {
func configureCalendar(_ calendar: JTAppleCalendarView) -> ConfigurationParameters {
dateFormatter.dateFormat = "yyyy MM dd"
let parameter = ConfigurationParameters(startDate: Date(),
endDate: dateFormatter.date(from: "2020 01 01")!,
numberOfRows: 6,
generateInDates: .forAllMonths,
generateOutDates: .off,
firstDayOfWeek: .monday)

    return parameter
}

}

@bivant
Copy link

bivant commented Apr 4, 2019

func calendar(_ calendar: JTAppleCalendarView, willDisplay cell: JTAppleCell, forItemAt date: Date, cellState: CellState, indexPath: IndexPath) {

}

Please implement the willDisplayCell function as stated here --> #553

@patchthecode
Copy link
Owner

@bivant is correct.
Closing this issue.
It is mentioned in very bold letters on the main page

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants