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

is it possible to select dates in the range in recent version of fscalender? #609

Closed
shilpashreemayigaiah opened this issue Mar 8, 2017 · 3 comments

Comments

@shilpashreemayigaiah
Copy link

The following informations are requested in a bug report

  • A brief bug description.
  • Stack trace.
  • Integration method.(manually/cocoapods/carthage)
  • Full steps to reproduce.
  • Device modal and iOS version. e.g. iPhone 6s iOS9.1
  • Xcode version. e.g. Xcode 8.1
  • FSCalendar version. e.g. FSCalenda 2.5.1
  • Does this happen in the demo project? Which one? Or a link to another demo project.

如果在使用过程中遇到问题,请提供以下信息以便于尽快将问题修复

  • 简单描述一下问题。
  • 控制台输出的堆栈跟踪(如果有的话)。
  • 安装方式. 如手动安装、cocoapods安装、或者通过carthage安装
  • 能够重现此问题的完整步骤。
  • 设备型号及版本。 例如: iPhone6s iOS9.1
  • 使用的Xcode版本。 例如: Xcode8.1
  • FSCalendar版本. 例如: FSCalendar 2.5.1
  • 是否能在demo中重现,以及在哪个demo中重现?或者附加一个重现问题的demo链接。
@WenchaoD
Copy link
Owner

WenchaoD commented Mar 8, 2017

No. Just call [calendar selectDate:] for each date.

@WenchaoD WenchaoD closed this as completed Mar 8, 2017
@AdrianBinDC
Copy link

AdrianBinDC commented Dec 2, 2017

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)
  }
}

@abhinav2014
Copy link

Awesome. Thanks.

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