(manually/cocoapods/carthage)e.g. iPhone 6s iOS9.1e.g. Xcode 8.1e.g. FSCalenda 2.5.1如手动安装、cocoapods安装、或者通过carthage安装。例如: iPhone6s iOS9.1例如: Xcode8.1例如: FSCalendar 2.5.1No. Just call [calendar selectDate:] for each date.
Here's a workaround I created for this limitation. In your view controller, create three variables and set the delegate:
1) var startDate: Date?
2) var endDate: Date?
3) selectedDateArray: [Date] = [] // empty array
4) calendarView.delegate = self
5) Implement the FSCalendarDelegate methods for didSelect and didDeselect.
Here's the code:
var selectedDateArray: [Date] = [] {
didSet {
// sort the array
selectedDateArray = calendarView.selectedDates.sorted()
switch selectedDateArray.count {
case 0:
startDate = nil
endDate = nil
case 1:
startDate = selectedDateArray.first
endDate = nil
case _ where selectedDateArray.count > 1:
startDate = selectedDateArray.first
endDate = selectedDateArray.last
var nextDay = Calendar.current.date(byAdding: .day, value: 1, to: startDate!)
while nextDay!.startOfDay <= endDate! {
calendarView.select(nextDay)
nextDay = Calendar.current.date(byAdding: .day, value: 1, to: nextDay!)
}
default:
return
}
}
}
var startDate: Date? {
didSet {
startDate = startDate?.startOfDay
}
}
var endDate: Date? {
didSet {
endDate = endDate?.endOfDay
}
}
extension ViewController: FSCalendarDelegate {
func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) {
if date.isAfterDate(Date().endOfDay!) {
calendar.deselect(date)
} else {
selectedDateArray.append(date)
}
}
func calendar(_ calendar: FSCalendar, didDeselect date: Date, at monthPosition: FSCalendarMonthPosition) {
if calendar.selectedDates.count > 2 {
let datesToDeselect: [Date] = calendar.selectedDates.filter{ $0 > date }
datesToDeselect.forEach{ calendar.deselect($0) }
calendar.select(date) // adds back the end date that was just deselected so it matches selectedDateArray
}
selectedDateArray = selectedDateArray.filter{ $0 < date }
selectedDateArray.forEach{calendarView.select($0)}
}
}
Here are the Date extension methods I used:
extension Date {
func isSameDate(_ comparisonDate: Date) -> Bool {
let order = Calendar.current.compare(self, to: comparisonDate, toGranularity: .day)
return order == .orderedSame
}
func isBeforeDate(_ comparisonDate: Date) -> Bool {
let order = Calendar.current.compare(self, to: comparisonDate, toGranularity: .day)
return order == .orderedAscending
}
func isAfterDate(_ comparisonDate: Date) -> Bool {
let order = Calendar.current.compare(self, to: comparisonDate, toGranularity: .day)
return order == .orderedDescending
}
var startOfDay: Date {
return Calendar.current.startOfDay(for: self)
}
var endOfDay: Date? {
var components = DateComponents()
components.day = 1
components.second = -1
return Calendar.current.date(byAdding: components, to: startOfDay)
}
}
Awesome. Thanks.
Most helpful comment
Here's a workaround I created for this limitation. In your view controller, create three variables and set the delegate:
1)
var startDate: Date?2)
var endDate: Date?3)
selectedDateArray: [Date] = [] // empty array4)
calendarView.delegate = self5) Implement the FSCalendarDelegate methods for
didSelectanddidDeselect.Here's the code:
Here are the
Dateextension methods I used: