在 fscalendar 中禁用过去的日子
Posted
技术标签:
【中文标题】在 fscalendar 中禁用过去的日子【英文标题】:disabling past days in fscalendar 【发布时间】:2018-05-12 15:38:46 【问题描述】:我正在使用 fscalender 并且正在禁用用户选择的日期,如下所示:
func getUserSelectedDates(_ arrWeekDay: [Int], calender calenderVW: FSCalendar?) -> NSMutableArray
let arrUnAvailibilityDates = NSMutableArray()
let currentDate: Date? = calenderVW?.currentPage
//get calender
let gregorianCalendar = Calendar.init(identifier: .gregorian)
// Start out by getting just the year, month and day components of the current date.
var components: DateComponents? = nil
if let aDate = currentDate
components = gregorianCalendar.dateComponents([.year, .month, .day, .weekday], from: aDate)
print(aDate)
// Change the Day component to 1 (for the first day of the month), and zero out the time components.
components?.day = 1
components?.hour = 0
components?.minute = 0
components?.second = 0
//get first day of current month
var firstDateOfCurMonth: Date? = nil
if let aComponents = components
firstDateOfCurMonth = gregorianCalendar.date(from: aComponents)
//create new component to get weekday of first date
var newcomponents: DateComponents? = nil
if let aMonth = firstDateOfCurMonth
newcomponents = gregorianCalendar.dateComponents([.year, .month, .day, .weekday], from: aMonth)
let firstDateWeekDay: Int? = newcomponents?.weekday
//get last month date
let curMonth: Int? = newcomponents?.month
newcomponents?.month = (curMonth ?? 0) + 1
var templastDateOfCurMonth: Date? = nil
if let aNewcomponents = newcomponents
templastDateOfCurMonth = gregorianCalendar.date(from: aNewcomponents)?.addingTimeInterval(-1)
// One second before the start of next month
var lastcomponents: DateComponents? = nil
if let aMonth = templastDateOfCurMonth
lastcomponents = gregorianCalendar.dateComponents([.year, .month, .day, .weekday], from: aMonth)
lastcomponents?.hour = 0
lastcomponents?.minute = 0
lastcomponents?.second = 0
var lastDateOfCurMonth: Date? = nil
if let aLastcomponents = lastcomponents
lastDateOfCurMonth = gregorianCalendar.date(from: aLastcomponents)
var dayDifference = DateComponents()
dayDifference.calendar = gregorianCalendar
if arrWeekDay.count == 0
else if arrWeekDay.count == 1
let wantedWeekDay = Int(arrWeekDay[0])
var firstWeekDateOfCurMonth: Date? = nil
if wantedWeekDay == firstDateWeekDay
firstWeekDateOfCurMonth = firstDateOfCurMonth
else
var day: Int = wantedWeekDay - firstDateWeekDay!
if day < 0
day += 7
day += 1
components?.day = day
firstWeekDateOfCurMonth = gregorianCalendar.date(from: components!)
var weekOffset: Int = 0
var nextDate: Date? = firstWeekDateOfCurMonth
repeat
let strDT: String = getSmallFormatedDate(convertCalendarDate(toNormalDate: nextDate))!
arrUnAvailibilityDates.add(strDT)
weekOffset += 1
dayDifference.weekOfYear = weekOffset
var date: Date? = nil
if let aMonth = firstWeekDateOfCurMonth
date = gregorianCalendar.date(byAdding: dayDifference, to: aMonth)
nextDate = date
while nextDate?.compare(lastDateOfCurMonth!) == .orderedAscending || nextDate?.compare(lastDateOfCurMonth!) == .orderedSame
else
for i in 0..<arrWeekDay.count
let wantedWeekDay = Int(arrWeekDay[i])
var firstWeekDateOfCurMonth: Date? = nil
if wantedWeekDay == firstDateWeekDay
firstWeekDateOfCurMonth = firstDateOfCurMonth
else
var day: Int = wantedWeekDay - firstDateWeekDay!
if day < 0
day += 7
day += 1
components?.day = day
firstWeekDateOfCurMonth = gregorianCalendar.date(from: components!)
var weekOffset: Int = 0
var nextDate: Date? = firstWeekDateOfCurMonth
repeat
let strDT = getSmallFormatedDate(convertCalendarDate(toNormalDate: nextDate))
arrUnAvailibilityDates.add(strDT!)
weekOffset += 1
dayDifference.weekOfYear = weekOffset
var date: Date? = nil
if let aMonth = firstWeekDateOfCurMonth
date = gregorianCalendar.date(byAdding: dayDifference, to: aMonth)
nextDate = date
while nextDate?.compare(lastDateOfCurMonth!) == .orderedAscending || nextDate?.compare(lastDateOfCurMonth!) == .orderedSame
return arrUnAvailibilityDates
func getSmallFormatedDate(_ localDate: Date?) -> String?
let dateFormatter = DateFormatter()
let timeZone = NSTimeZone(name: "UTC")
if let aZone = timeZone
dateFormatter.timeZone = aZone as TimeZone
dateFormatter.dateFormat = "yyyy-MM-dd"
var dateString: String? = nil
if let aDate = localDate
dateString = dateFormatter.string(from: aDate)
return dateString
func convertCalendarDate(toNormalDate selectedDate: Date?) -> Date?
let sourceTimeZone = NSTimeZone(abbreviation: "UTC")
let destinationTimeZone = NSTimeZone.system as NSTimeZone
var sourceGMTOffset: Int? = nil
if let aDate = selectedDate
sourceGMTOffset = sourceTimeZone?.secondsFromGMT(for: aDate)
var destinationGMTOffset: Int? = nil
if let aDate = selectedDate
destinationGMTOffset = destinationTimeZone.secondsFromGMT(for: aDate)
let interval1 = TimeInterval((destinationGMTOffset ?? 0) - (sourceGMTOffset ?? 0))
var localDate: Date? = nil
if let aDate = selectedDate
localDate = Date(timeInterval: interval1, since: aDate)
return localDate
extension CalenderViewController: FSCalendarDelegate, FSCalendarDataSource, FSCalendarDelegateAppearance
func calendar(_ calendar: FSCalendar, boundingRectWillChange bounds: CGRect, animated: Bool)
self.view.layoutIfNeeded()
func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition)
self.date = dateFormatter2.string(from: date)
func calendarCurrentPageDidChange(_ calendar: FSCalendar)
arrDates = self.getUserSelectedDates(days, calender: self.calendar)
calendar.reloadData()
func calendar(_ calendar: FSCalendar, appearance: FSCalendarAppearance, titleDefaultColorFor date: Date) -> UIColor?
if arrDates.contains(dateFormatter2.string(from: date))
return UIColor.darkGray
else
return UIColor.lightGray
func calendar(_ calendar: FSCalendar, shouldSelect date: Date, at monthPosition: FSCalendarMonthPosition) -> Bool
if arrDates.contains(dateFormatter2.string(from: date)))
return true
else
return false
这是完美的工作..现在我试图在 fscalender 中禁用过去的日子..我试过这个:
func calendar(_ calendar: FSCalendar, shouldSelect date: Date, at monthPosition: FSCalendarMonthPosition) -> Bool
if arrDates.contains(dateFormatter2.string(from: date)) && (date > calendar.currentPage)
return true
else
return false
但它对我不起作用......
我还注意到当前日期是错误的!我不断得到
2018-04-30 21:00:00 +0000
而今天的日期是 2018-05-12
如何解决这个问题并禁用过去的日子?
【问题讨论】:
【参考方案1】:您只需将所选日期与当前日期进行比较。如果它比return false
升序,否则return true
在shouldSelect
方法中,如下所示。
只尝试一种解决方案。
1.解决方案(当您滑动查看上个月时,它会显示上个月,此解决方案将当前日期视为过去日期,因为存在时差)
func calendar(_ calendar: FSCalendar, shouldSelect date: Date, at monthPosition: FSCalendarMonthPosition) -> Bool
if date .compare(Date()) == .orderedAscending
return false
else
return true
2。解决方案(这不会显示过去的月份,在此解决方案中您还可以选择当前日期)
func minimumDate(for calendar: FSCalendar) -> Date
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let myString = formatter.string(from: Date())
let yourDate = formatter.date(from: myString)
formatter.dateFormat = "yyyy-MM-dd"
let strCurrentDate = formatter.string(from: yourDate!)
return self.dateFormatter2.date(from: strCurrentDate)!
【讨论】:
【参考方案2】:您可以使用此委托方法禁用过去的日期
func minimumDate(for calendar: FSCalendar) -> Date
return Date()
【讨论】:
以上是关于在 fscalendar 中禁用过去的日子的主要内容,如果未能解决你的问题,请参考以下文章